802 lines
21 KiB
C
802 lines
21 KiB
C
|
/********************************************************************/
|
|||
|
/** Copyright(c) 1995 Microsoft Corporation. **/
|
|||
|
/********************************************************************/
|
|||
|
|
|||
|
//***
|
|||
|
//
|
|||
|
// Filename: ifobject.c
|
|||
|
//
|
|||
|
// Description: Routines to manipulate ROUTER_INTERFACE_OBJECTs
|
|||
|
//
|
|||
|
// History: May 11,1995 NarenG Created original version.
|
|||
|
//
|
|||
|
|
|||
|
#include "dimsvcp.h"
|
|||
|
#include <netconp.h>
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: GetNewIfHandle
|
|||
|
//
|
|||
|
// Returns: Handle for new interface
|
|||
|
//
|
|||
|
// Description: Will generate an id that will be used for an handle to the new
|
|||
|
// interface.
|
|||
|
//
|
|||
|
HANDLE
|
|||
|
GetNewIfHandle(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
static DWORD Id = 2;
|
|||
|
|
|||
|
return( (HANDLE)UlongToPtr(Id++) );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectAllocateAndInit
|
|||
|
//
|
|||
|
// Returns: ROUTER_INTERFACE_OBJECT * - Success
|
|||
|
// NULL - Failure
|
|||
|
//
|
|||
|
// Description: Allocates and initializes a ROUTER_INTERFACE_OBJECT structure
|
|||
|
//
|
|||
|
ROUTER_INTERFACE_OBJECT *
|
|||
|
IfObjectAllocateAndInit(
|
|||
|
IN LPWSTR lpwstrName,
|
|||
|
IN ROUTER_INTERFACE_STATE State,
|
|||
|
IN ROUTER_INTERFACE_TYPE IfType,
|
|||
|
IN HCONN hConnection,
|
|||
|
IN BOOL fEnabled,
|
|||
|
IN DWORD dwInterfaceReachableAfterSecondsMin,
|
|||
|
IN DWORD dwInterfaceReachableAfterSecondsMax,
|
|||
|
IN LPWSTR lpwsDialoutHoursRestriction
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwRetCode;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
DWORD dwIfObjectSize;
|
|||
|
DWORD dwTransportIndex;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// On a workstation we do not allow creation of demand-dial interfaces
|
|||
|
//
|
|||
|
|
|||
|
if ( gblDIMConfigInfo.NtProductType == NtProductWinNt )
|
|||
|
{
|
|||
|
if ( ( IfType == ROUTER_IF_TYPE_FULL_ROUTER ) )
|
|||
|
{
|
|||
|
WCHAR * pChar = lpwstrName;
|
|||
|
|
|||
|
DIMLogWarning( ROUTERLOG_LIMITED_WKSTA_SUPPORT,1, &pChar );
|
|||
|
|
|||
|
SetLastError( ERROR_NOT_SUPPORTED );
|
|||
|
|
|||
|
return( (ROUTER_INTERFACE_OBJECT *)NULL );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Hardcode to 2 routermanagers, one for IP, one for IPX. We need to do this
|
|||
|
// because then we do not need to reallocate the size to accomodate a new protocol
|
|||
|
// when it is added dynamically to the router
|
|||
|
//
|
|||
|
|
|||
|
dwIfObjectSize = sizeof( ROUTER_INTERFACE_OBJECT )
|
|||
|
+ ( sizeof( ROUTER_INTERFACE_TRANSPORT ) * 2 );
|
|||
|
|
|||
|
pIfObject = (ROUTER_INTERFACE_OBJECT *)LOCAL_ALLOC( LPTR, dwIfObjectSize );
|
|||
|
|
|||
|
if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
|
|||
|
{
|
|||
|
return( (ROUTER_INTERFACE_OBJECT *)NULL );
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->lpwsInterfaceName = (LPWSTR)LOCAL_ALLOC( LPTR,
|
|||
|
(wcslen(lpwstrName)+1)
|
|||
|
* sizeof(WCHAR) );
|
|||
|
|
|||
|
if ( pIfObject->lpwsInterfaceName == (LPWSTR)NULL )
|
|||
|
{
|
|||
|
IfObjectFree( pIfObject );
|
|||
|
|
|||
|
return( (ROUTER_INTERFACE_OBJECT *)NULL );
|
|||
|
}
|
|||
|
|
|||
|
if ( ( IfType == ROUTER_IF_TYPE_DEDICATED ) ||
|
|||
|
( IfType == ROUTER_IF_TYPE_TUNNEL1 ) ||
|
|||
|
( IfType == ROUTER_IF_TYPE_INTERNAL ) )
|
|||
|
{
|
|||
|
if ( !fEnabled )
|
|||
|
{
|
|||
|
WCHAR * pChar = lpwstrName;
|
|||
|
|
|||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|||
|
|
|||
|
DIMLogErrorString( ROUTERLOG_COULDNT_LOAD_IF, 1, &pChar,
|
|||
|
ERROR_INVALID_PARAMETER, 1 );
|
|||
|
|
|||
|
IfObjectFree( pIfObject );
|
|||
|
|
|||
|
return( (ROUTER_INTERFACE_OBJECT *)NULL );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->dwReachableAfterSecondsMin=dwInterfaceReachableAfterSecondsMin;
|
|||
|
pIfObject->dwReachableAfterSecondsMax=dwInterfaceReachableAfterSecondsMax;
|
|||
|
pIfObject->dwReachableAfterSeconds =dwInterfaceReachableAfterSecondsMin;
|
|||
|
|
|||
|
wcscpy( pIfObject->lpwsInterfaceName, lpwstrName );
|
|||
|
|
|||
|
pIfObject->State = State;
|
|||
|
pIfObject->IfType = IfType;
|
|||
|
pIfObject->hConnection = hConnection;
|
|||
|
pIfObject->hDIMInterface = ( IfType == ROUTER_IF_TYPE_LOOPBACK )
|
|||
|
? (HANDLE)1
|
|||
|
: GetNewIfHandle();
|
|||
|
pIfObject->fFlags = ( fEnabled ) ? IFFLAG_ENABLED : 0;
|
|||
|
pIfObject->hEventNotifyCaller = INVALID_HANDLE_VALUE;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the router manager handles
|
|||
|
//
|
|||
|
|
|||
|
for ( dwTransportIndex = 0;
|
|||
|
dwTransportIndex < gblDIMConfigInfo.dwNumRouterManagers;
|
|||
|
dwTransportIndex++ )
|
|||
|
{
|
|||
|
pIfObject->Transport[dwTransportIndex].hInterface=INVALID_HANDLE_VALUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If we are running in LANONLYMode then we do not care about media bits
|
|||
|
//
|
|||
|
|
|||
|
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
|
|||
|
{
|
|||
|
return( pIfObject );
|
|||
|
}
|
|||
|
|
|||
|
if ( ( IfType == ROUTER_IF_TYPE_FULL_ROUTER ) )
|
|||
|
{
|
|||
|
DWORD (*IfObjectLoadPhonebookInfo)( ROUTER_INTERFACE_OBJECT * ) =
|
|||
|
(DWORD(*)( ROUTER_INTERFACE_OBJECT * ))
|
|||
|
GetDDMEntryPoint("IfObjectLoadPhonebookInfo");
|
|||
|
|
|||
|
//
|
|||
|
// Load phonebook information for this interface
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = IfObjectLoadPhonebookInfo( pIfObject );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
if ( dwRetCode == ERROR_INTERFACE_HAS_NO_DEVICES )
|
|||
|
{
|
|||
|
pIfObject->fFlags |= IFFLAG_OUT_OF_RESOURCES;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
WCHAR * pChar = lpwstrName;
|
|||
|
|
|||
|
DIMLogErrorString( ROUTERLOG_COULDNT_LOAD_IF, 1, &pChar,
|
|||
|
dwRetCode, 1 );
|
|||
|
|
|||
|
SetLastError( dwRetCode );
|
|||
|
|
|||
|
IfObjectFree( pIfObject );
|
|||
|
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->lpwsDialoutHoursRestriction = lpwsDialoutHoursRestriction;
|
|||
|
}
|
|||
|
|
|||
|
return( pIfObject );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectInsertInTable
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// ERROR_MAX_WAN_INTERFACE_LIMIT - Failure
|
|||
|
// ERROR_MAX_LAN_INTERFACE_LIMIT - Failure
|
|||
|
// ERROR_MAX_CLIENT_INTERFACE_LIMIT - Failure
|
|||
|
//
|
|||
|
// Description: Will insert this interface object into the interface object
|
|||
|
// table
|
|||
|
//
|
|||
|
DWORD
|
|||
|
IfObjectInsertInTable(
|
|||
|
IN ROUTER_INTERFACE_OBJECT * pIfObject
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwBucketIndex=IfObjectHashIfHandleToBucket(pIfObject->hDIMInterface);
|
|||
|
|
|||
|
if ( pIfObject->IfType == ROUTER_IF_TYPE_FULL_ROUTER )
|
|||
|
{
|
|||
|
if ( gblInterfaceTable.dwNumWanInterfaces == DIM_MAX_WAN_INTERFACES )
|
|||
|
{
|
|||
|
return( ERROR_MAX_WAN_INTERFACE_LIMIT );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
gblInterfaceTable.dwNumWanInterfaces++;
|
|||
|
}
|
|||
|
}
|
|||
|
else if ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED )
|
|||
|
{
|
|||
|
if ( gblInterfaceTable.dwNumLanInterfaces == DIM_MAX_LAN_INTERFACES )
|
|||
|
{
|
|||
|
return( ERROR_MAX_LAN_INTERFACE_LIMIT );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
gblInterfaceTable.dwNumLanInterfaces++;
|
|||
|
}
|
|||
|
}
|
|||
|
else if ( pIfObject->IfType == ROUTER_IF_TYPE_CLIENT )
|
|||
|
{
|
|||
|
if (gblInterfaceTable.dwNumClientInterfaces==DIM_MAX_CLIENT_INTERFACES)
|
|||
|
{
|
|||
|
return( ERROR_MAX_CLIENT_INTERFACE_LIMIT );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
gblInterfaceTable.dwNumClientInterfaces++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->pNext = gblInterfaceTable.IfBucket[dwBucketIndex];
|
|||
|
|
|||
|
gblInterfaceTable.IfBucket[dwBucketIndex] = pIfObject;
|
|||
|
|
|||
|
gblInterfaceTable.dwNumTotalInterfaces++;
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
ROUTER_INTERFACE_OBJECT *
|
|||
|
IfObjectGetPointer(
|
|||
|
IN HANDLE hDIMInterface
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwBucketIndex;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
|
|||
|
dwBucketIndex = IfObjectHashIfHandleToBucket(hDIMInterface);
|
|||
|
|
|||
|
for( pIfObject = gblInterfaceTable.IfBucket[dwBucketIndex];
|
|||
|
pIfObject != (ROUTER_INTERFACE_OBJECT *)NULL;
|
|||
|
pIfObject = pIfObject->pNext )
|
|||
|
{
|
|||
|
if ( pIfObject->hDIMInterface == hDIMInterface )
|
|||
|
{
|
|||
|
return( pIfObject );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( (ROUTER_INTERFACE_OBJECT *)NULL );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectHashIfHandleToBucket
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
DWORD
|
|||
|
IfObjectHashIfHandleToBucket(
|
|||
|
IN HANDLE hDIMInterface
|
|||
|
)
|
|||
|
{
|
|||
|
return( (DWORD)((ULONG_PTR)hDIMInterface) % NUM_IF_BUCKETS );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectRemove
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
VOID
|
|||
|
IfObjectRemove(
|
|||
|
IN HANDLE hDIMInterface
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwBucketIndex;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObjectPrev;
|
|||
|
|
|||
|
dwBucketIndex = IfObjectHashIfHandleToBucket(hDIMInterface);
|
|||
|
|
|||
|
pIfObject = gblInterfaceTable.IfBucket[dwBucketIndex];
|
|||
|
pIfObjectPrev = pIfObject;
|
|||
|
|
|||
|
while( pIfObject != (ROUTER_INTERFACE_OBJECT *)NULL )
|
|||
|
{
|
|||
|
if ( pIfObject->hDIMInterface == hDIMInterface )
|
|||
|
{
|
|||
|
if ( gblInterfaceTable.IfBucket[dwBucketIndex] == pIfObject )
|
|||
|
{
|
|||
|
gblInterfaceTable.IfBucket[dwBucketIndex] = pIfObject->pNext;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pIfObjectPrev->pNext = pIfObject->pNext;
|
|||
|
}
|
|||
|
|
|||
|
gblInterfaceTable.dwNumTotalInterfaces--;
|
|||
|
|
|||
|
if ( pIfObject->IfType == ROUTER_IF_TYPE_FULL_ROUTER )
|
|||
|
{
|
|||
|
gblInterfaceTable.dwNumWanInterfaces--;
|
|||
|
}
|
|||
|
else if ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED )
|
|||
|
{
|
|||
|
gblInterfaceTable.dwNumLanInterfaces--;
|
|||
|
}
|
|||
|
else if ( pIfObject->IfType == ROUTER_IF_TYPE_CLIENT )
|
|||
|
{
|
|||
|
gblInterfaceTable.dwNumClientInterfaces--;
|
|||
|
}
|
|||
|
|
|||
|
IfObjectFree( pIfObject );
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
pIfObjectPrev = pIfObject;
|
|||
|
pIfObject = pIfObject->pNext;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectFree
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// Non-zero returns - Failure
|
|||
|
//
|
|||
|
// Description: Will release all memory allocated for the interfae object.
|
|||
|
//
|
|||
|
VOID
|
|||
|
IfObjectFree(
|
|||
|
IN ROUTER_INTERFACE_OBJECT * pIfObject
|
|||
|
)
|
|||
|
{
|
|||
|
if ( pIfObject->lpwsInterfaceName != NULL )
|
|||
|
{
|
|||
|
LOCAL_FREE( pIfObject->lpwsInterfaceName );
|
|||
|
}
|
|||
|
|
|||
|
if ( pIfObject->lpwsDialoutHoursRestriction != NULL )
|
|||
|
{
|
|||
|
LOCAL_FREE( pIfObject->lpwsDialoutHoursRestriction );
|
|||
|
}
|
|||
|
|
|||
|
LOCAL_FREE( pIfObject );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectGetPointerByName
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
ROUTER_INTERFACE_OBJECT *
|
|||
|
IfObjectGetPointerByName(
|
|||
|
IN LPWSTR lpwstrName,
|
|||
|
IN BOOL fIncludeClientInterfaces
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwBucketIndex;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
|
|||
|
for ( dwBucketIndex = 0; dwBucketIndex < NUM_IF_BUCKETS; dwBucketIndex++ )
|
|||
|
{
|
|||
|
for( pIfObject = gblInterfaceTable.IfBucket[dwBucketIndex];
|
|||
|
pIfObject != (ROUTER_INTERFACE_OBJECT *)NULL;
|
|||
|
pIfObject = pIfObject->pNext )
|
|||
|
{
|
|||
|
if ( _wcsicmp( pIfObject->lpwsInterfaceName, lpwstrName ) == 0 )
|
|||
|
{
|
|||
|
if ( pIfObject->IfType == ROUTER_IF_TYPE_CLIENT )
|
|||
|
{
|
|||
|
if ( fIncludeClientInterfaces )
|
|||
|
{
|
|||
|
return( pIfObject );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( pIfObject );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( (ROUTER_INTERFACE_OBJECT *)NULL );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectDoesLanInterfaceExist
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// Non-zero returns - Failure
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
BOOL
|
|||
|
IfObjectDoesLanInterfaceExist(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwBucketIndex;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
|
|||
|
for ( dwBucketIndex = 0; dwBucketIndex < NUM_IF_BUCKETS; dwBucketIndex++ )
|
|||
|
{
|
|||
|
for( pIfObject = gblInterfaceTable.IfBucket[dwBucketIndex];
|
|||
|
pIfObject != (ROUTER_INTERFACE_OBJECT *)NULL;
|
|||
|
pIfObject = pIfObject->pNext )
|
|||
|
{
|
|||
|
if ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED )
|
|||
|
{
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectWANDeviceInstalled
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description: Called by DDM whenever a WAN device is installed or removed
|
|||
|
//
|
|||
|
VOID
|
|||
|
IfObjectWANDeviceInstalled(
|
|||
|
IN BOOL fWANDeviceInstalled
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwXportIndex = GetTransportIndex( PID_IP );
|
|||
|
|
|||
|
//
|
|||
|
// If a WAN device is installed and IP is installed then we
|
|||
|
// start advertizing on specific multicast address so as to make this
|
|||
|
// router discoverable
|
|||
|
//
|
|||
|
|
|||
|
if ( ( fWANDeviceInstalled ) && ( dwXportIndex != (DWORD)-1 ) )
|
|||
|
{
|
|||
|
DWORD dwRetCode =
|
|||
|
gblRouterManagers[dwXportIndex].DdmRouterIf.SetRasAdvEnable(
|
|||
|
fWANDeviceInstalled );
|
|||
|
|
|||
|
DIMTRACE2( "Calling SetRasAdvEnable( %d ) = %d",
|
|||
|
fWANDeviceInstalled, dwRetCode );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectNotifyOfMediaSenseChange
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description: Notifies the object of change in reachablity status due to
|
|||
|
// media sense.
|
|||
|
//
|
|||
|
//
|
|||
|
VOID
|
|||
|
IfObjectNotifyOfMediaSenseChange(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwBucketIndex;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
|
|||
|
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
|
|||
|
|
|||
|
for ( dwBucketIndex = 0; dwBucketIndex < NUM_IF_BUCKETS; dwBucketIndex++ )
|
|||
|
{
|
|||
|
for( pIfObject = gblInterfaceTable.IfBucket[dwBucketIndex];
|
|||
|
pIfObject != (ROUTER_INTERFACE_OBJECT *)NULL;
|
|||
|
pIfObject = pIfObject->pNext )
|
|||
|
{
|
|||
|
if ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED )
|
|||
|
{
|
|||
|
DWORD dwInactiveReason;
|
|||
|
|
|||
|
if ( IfObjectIsLANDeviceActive( pIfObject->lpwsInterfaceName,
|
|||
|
&dwInactiveReason ) )
|
|||
|
{
|
|||
|
if ( pIfObject->State != RISTATE_CONNECTED )
|
|||
|
{
|
|||
|
pIfObject->State = RISTATE_CONNECTED;
|
|||
|
|
|||
|
pIfObject->fFlags &= ~IFFLAG_NO_MEDIA_SENSE;
|
|||
|
|
|||
|
IfObjectNotifyOfReachabilityChange(
|
|||
|
pIfObject,
|
|||
|
TRUE,
|
|||
|
INTERFACE_NO_MEDIA_SENSE );
|
|||
|
}
|
|||
|
}
|
|||
|
else if ( dwInactiveReason == INTERFACE_NO_MEDIA_SENSE )
|
|||
|
{
|
|||
|
if ( pIfObject->State != RISTATE_DISCONNECTED )
|
|||
|
{
|
|||
|
pIfObject->State = RISTATE_DISCONNECTED;
|
|||
|
|
|||
|
pIfObject->fFlags |= IFFLAG_NO_MEDIA_SENSE;
|
|||
|
|
|||
|
IfObjectNotifyOfReachabilityChange(
|
|||
|
pIfObject,
|
|||
|
FALSE,
|
|||
|
INTERFACE_NO_MEDIA_SENSE );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectNotifyOfReachabilityChange
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description: Notifies the object of change in reachablity status due to
|
|||
|
// media sense.
|
|||
|
//
|
|||
|
//
|
|||
|
VOID
|
|||
|
IfObjectNotifyOfReachabilityChange(
|
|||
|
IN ROUTER_INTERFACE_OBJECT * pIfObject,
|
|||
|
IN BOOL fReachable,
|
|||
|
IN UNREACHABILITY_REASON dwReason
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwIndex;
|
|||
|
WCHAR wchFriendlyName[MAX_INTERFACE_NAME_LEN+1];
|
|||
|
LPWSTR lpszFriendlyName = wchFriendlyName;
|
|||
|
|
|||
|
for ( dwIndex = 0;
|
|||
|
dwIndex < gblDIMConfigInfo.dwNumRouterManagers;
|
|||
|
dwIndex++ )
|
|||
|
{
|
|||
|
if ( pIfObject->Transport[dwIndex].hInterface == INVALID_HANDLE_VALUE )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if ( fReachable )
|
|||
|
{
|
|||
|
DIMTRACE2( "Notifying Protocol = 0x%x, Interface=%ws is Reachable",
|
|||
|
gblRouterManagers[dwIndex].DdmRouterIf.dwProtocolId,
|
|||
|
pIfObject->lpwsInterfaceName );
|
|||
|
|
|||
|
gblRouterManagers[dwIndex].DdmRouterIf.InterfaceReachable(
|
|||
|
pIfObject->Transport[dwIndex].hInterface );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DIMTRACE3(
|
|||
|
"Notifying Protocol = 0x%x,Interface=%ws is UnReachable=%d",
|
|||
|
gblRouterManagers[dwIndex].DdmRouterIf.dwProtocolId,
|
|||
|
pIfObject->lpwsInterfaceName,
|
|||
|
dwReason );
|
|||
|
|
|||
|
gblRouterManagers[dwIndex].DdmRouterIf.InterfaceNotReachable(
|
|||
|
pIfObject->Transport[dwIndex].hInterface,
|
|||
|
dwReason );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( MprConfigGetFriendlyName( gblDIMConfigInfo.hMprConfig,
|
|||
|
pIfObject->lpwsInterfaceName,
|
|||
|
wchFriendlyName,
|
|||
|
sizeof( wchFriendlyName ) ) != NO_ERROR )
|
|||
|
{
|
|||
|
wcscpy( wchFriendlyName, pIfObject->lpwsInterfaceName );
|
|||
|
}
|
|||
|
|
|||
|
if ( fReachable )
|
|||
|
{
|
|||
|
DIMLogInformation(ROUTERLOG_IF_REACHABLE,1, &lpszFriendlyName );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DWORD dwEventLogId = 0;
|
|||
|
|
|||
|
switch( dwReason )
|
|||
|
{
|
|||
|
case INTERFACE_OUT_OF_RESOURCES:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON1;
|
|||
|
break;
|
|||
|
case INTERFACE_CONNECTION_FAILURE:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON2;
|
|||
|
break;
|
|||
|
case INTERFACE_DISABLED:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON3;
|
|||
|
break;
|
|||
|
case INTERFACE_SERVICE_IS_PAUSED:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON4;
|
|||
|
break;
|
|||
|
case INTERFACE_DIALOUT_HOURS_RESTRICTION:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON5;
|
|||
|
break;
|
|||
|
case INTERFACE_NO_MEDIA_SENSE:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON6;
|
|||
|
break;
|
|||
|
case INTERFACE_NO_DEVICE:
|
|||
|
dwEventLogId = ROUTERLOG_IF_UNREACHABLE_REASON7;
|
|||
|
break;
|
|||
|
default:
|
|||
|
dwEventLogId = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ( dwEventLogId != 0 )
|
|||
|
{
|
|||
|
DIMLogInformation( dwEventLogId, 1, &lpszFriendlyName );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectIsLANDeviceActive
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// Non-zero returns - Failure
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
BOOL
|
|||
|
IfObjectIsLANDeviceActive(
|
|||
|
IN LPWSTR lpwsInterfaceName,
|
|||
|
OUT LPDWORD lpdwInactiveReason
|
|||
|
)
|
|||
|
{
|
|||
|
NETCON_STATUS NetConStatus;
|
|||
|
HRESULT hResult;
|
|||
|
BOOL fEnabled;
|
|||
|
GUID Guid;
|
|||
|
NTSTATUS NtStatus;
|
|||
|
UNICODE_STRING usTemp;
|
|||
|
|
|||
|
//
|
|||
|
// First check media state
|
|||
|
//
|
|||
|
|
|||
|
usTemp.Length = wcslen(lpwsInterfaceName) * sizeof(WCHAR);
|
|||
|
usTemp.MaximumLength = usTemp.Length + sizeof(WCHAR);
|
|||
|
usTemp.Buffer = lpwsInterfaceName;
|
|||
|
|
|||
|
NtStatus = RtlGUIDFromString( &usTemp, &Guid );
|
|||
|
|
|||
|
if ( NtStatus != STATUS_SUCCESS )
|
|||
|
{
|
|||
|
*lpdwInactiveReason = INTERFACE_NO_DEVICE;
|
|||
|
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
hResult = HrGetPnpDeviceStatus( &Guid, &NetConStatus );
|
|||
|
|
|||
|
if ( HRESULT_CODE( hResult ) == NO_ERROR )
|
|||
|
{
|
|||
|
switch ( NetConStatus )
|
|||
|
{
|
|||
|
case NCS_MEDIA_DISCONNECTED:
|
|||
|
*lpdwInactiveReason = INTERFACE_NO_MEDIA_SENSE;
|
|||
|
return( FALSE );
|
|||
|
|
|||
|
case NCS_CONNECTED:
|
|||
|
case NCS_INVALID_ADDRESS:
|
|||
|
case NCS_AUTHENTICATING:
|
|||
|
case NCS_CREDENTIALS_REQUIRED:
|
|||
|
case NCS_AUTHENTICATION_FAILED:
|
|||
|
case NCS_AUTHENTICATION_SUCCEEDED:
|
|||
|
{
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
*lpdwInactiveReason = INTERFACE_NO_DEVICE;
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*lpdwInactiveReason = INTERFACE_NO_DEVICE;
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: IfObjectDeleteInterface
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description: Delete this interface with all the router managers.
|
|||
|
//
|
|||
|
//
|
|||
|
VOID
|
|||
|
IfObjectDeleteInterfaceFromTransport(
|
|||
|
IN ROUTER_INTERFACE_OBJECT * pIfObject,
|
|||
|
IN DWORD dwPid
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwIndex;
|
|||
|
DIM_ROUTER_INTERFACE * pDdmRouterIf;
|
|||
|
DWORD dwRetCode;
|
|||
|
|
|||
|
for ( dwIndex = 0;
|
|||
|
dwIndex < gblDIMConfigInfo.dwNumRouterManagers;
|
|||
|
dwIndex++ )
|
|||
|
{
|
|||
|
if ( pIfObject->Transport[dwIndex].hInterface == INVALID_HANDLE_VALUE )
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pDdmRouterIf=&(gblRouterManagers[dwIndex].DdmRouterIf);
|
|||
|
|
|||
|
if ( pDdmRouterIf->dwProtocolId == dwPid )
|
|||
|
{
|
|||
|
dwRetCode = pDdmRouterIf->DeleteInterface(
|
|||
|
pIfObject->Transport[dwIndex].hInterface );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
LPWSTR lpwsInsertStrings[2];
|
|||
|
|
|||
|
lpwsInsertStrings[0] = pIfObject->lpwsInterfaceName;
|
|||
|
lpwsInsertStrings[1] = ( pDdmRouterIf->dwProtocolId == PID_IP )
|
|||
|
? L"IP" : L"IPX";
|
|||
|
|
|||
|
DIMLogErrorString( ROUTERLOG_COULDNT_REMOVE_INTERFACE, 2,
|
|||
|
lpwsInsertStrings, dwRetCode, 2 );
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->Transport[dwIndex].hInterface = INVALID_HANDLE_VALUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|