windows-nt/Source/XPSP1/NT/net/rras/dim/server/ifapi.c
2020-09-26 16:20:57 +08:00

3519 lines
95 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************/
/** Copyright(c) 1995 Microsoft Corporation. **/
/********************************************************************/
//***
//
// Filename: ifapi.c
//
// Description: Contains code to process interface admin api requests
//
// History: May 11,1995 NarenG Created original version.
//
#include "dimsvcp.h"
#include <ras.h>
#include <dimsvc.h> // Generated by MIDL
#include "rpbk.h"
#include <mprapip.h>
#define MAX_GET_INFO_RETRIES 3
//
// DoStartRouter API interface
//
typedef struct _START_ROUTER_DATA
{
DWORD dwTransportId;
DWORD dwInterfaceInfoSize;
LPBYTE pInterfaceInfo;
DWORD dwGlobalInfoSize;
LPBYTE pGlobalInfo;
} START_ROUTER_DATA, *PSTART_ROUTER_DATA;
DWORD
RRouterDeviceEnum(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN OUT PDIM_INFORMATION_CONTAINER pInfoStruct,
OUT LPDWORD lpdwTotalEntries
)
{
DWORD dwAccessStatus;
DWORD dwRetCode = NO_ERROR;
LPRASDEVINFO lpRasDevInfo = NULL;
DWORD dwSize = 0, dwRetSize = 0;
DWORD dwcDevices = 0;
DWORD i = 0;
MPR_DEVICE_0* pDev0 = NULL;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwLevel != 0 )
{
return( ERROR_NOT_SUPPORTED );
}
do
{
*lpdwTotalEntries = 0;
// Find out how much memory to allocate
//
dwRetCode = RasEnumDevices(
NULL,
&dwSize,
&dwcDevices);
if ( ( dwRetCode != NO_ERROR ) &&
( dwRetCode != ERROR_BUFFER_TOO_SMALL )
)
{
break;
}
if ( dwSize == 0 )
{
dwRetCode = NO_ERROR;
break;
}
// Allocate the ras device info
//
lpRasDevInfo = LOCAL_ALLOC ( LPTR, dwSize );
if ( lpRasDevInfo == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
ZeroMemory(lpRasDevInfo, dwSize );
// Allocate the return value
//
dwRetSize = dwcDevices * sizeof(MPR_DEVICE_0);
pInfoStruct->pBuffer = MIDL_user_allocate( dwRetSize );
if ( pInfoStruct->pBuffer == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
ZeroMemory(pInfoStruct->pBuffer, dwRetSize );
pDev0 = (MPR_DEVICE_0*) pInfoStruct->pBuffer;
// Read in the device info
lpRasDevInfo->dwSize = sizeof(RASDEVINFO);
dwRetCode = RasEnumDevices(
lpRasDevInfo,
&dwSize,
&dwcDevices);
if ( dwRetCode == ERROR_BUFFER_TOO_SMALL )
{
dwRetCode = NO_ERROR;
}
if ( dwRetCode != NO_ERROR )
{
break;
}
// Copy the device info over
for ( i = 0; i < dwcDevices; i++ )
{
wcscpy(pDev0[i].szDeviceType, lpRasDevInfo[i].szDeviceType);
wcscpy(pDev0[i].szDeviceName, lpRasDevInfo[i].szDeviceName);
}
// Everything's ok, go ahead and set the return values
//
*lpdwTotalEntries = dwcDevices;
pInfoStruct->dwBufferSize = dwRetSize;
} while( FALSE );
// Cleanup
{
if ( lpRasDevInfo )
{
LOCAL_FREE( lpRasDevInfo );
}
if ( dwRetCode != NO_ERROR )
{
if ( pInfoStruct->pBuffer )
{
MIDL_user_free ( pInfoStruct->pBuffer );
pInfoStruct->pBuffer = NULL;
}
}
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"DeviceEnum returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: DoStartRouter
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description:
//
VOID
DoStartRouter(
IN PVOID pParameter
)
{
DWORD dwRetCode = NO_ERROR;
DWORD dwIndex = gblDIMConfigInfo.dwNumRouterManagers;
ROUTER_INTERFACE_OBJECT * pIfObject;
START_ROUTER_DATA * pStartRouterData = (START_ROUTER_DATA *)pParameter;
DWORD (*StartRouter)(
IN OUT DIM_ROUTER_INTERFACE * pDimRouterIf,
IN BOOL fLANModeOnly,
IN LPVOID pGlobalInfo );
//
// Wait for setup to finsh
//
Sleep( 15000 );
//
// Load the StartRouter
//
StartRouter = (PVOID)GetProcAddress( gblRouterManagers[dwIndex].hModule,
"StartRouter" );
if ( StartRouter == NULL )
{
if ( pStartRouterData->pInterfaceInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pInterfaceInfo );
}
if ( pStartRouterData->pGlobalInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pGlobalInfo );
}
LOCAL_FREE( pStartRouterData );
return;
}
gblRouterManagers[dwIndex].DdmRouterIf.ConnectInterface
= DIMConnectInterface;
gblRouterManagers[dwIndex].DdmRouterIf.DisconnectInterface
= DIMDisconnectInterface;
gblRouterManagers[dwIndex].DdmRouterIf.SaveInterfaceInfo
= DIMSaveInterfaceInfo;
gblRouterManagers[dwIndex].DdmRouterIf.RestoreInterfaceInfo
= DIMRestoreInterfaceInfo;
gblRouterManagers[dwIndex].DdmRouterIf.SaveGlobalInfo
= DIMSaveGlobalInfo;
gblRouterManagers[dwIndex].DdmRouterIf.RouterStopped
= DIMRouterStopped;
gblRouterManagers[dwIndex].DdmRouterIf.InterfaceEnabled
= DIMInterfaceEnabled;
dwRetCode = (*StartRouter)(
&(gblRouterManagers[dwIndex].DdmRouterIf),
gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN,
pStartRouterData->pGlobalInfo );
if ( dwRetCode != NO_ERROR )
{
DIMTRACE1( "Start Router failed with %d", dwRetCode );
if ( pStartRouterData->pInterfaceInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pInterfaceInfo );
}
if ( pStartRouterData->pGlobalInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pGlobalInfo );
}
LOCAL_FREE( pStartRouterData );
return;
}
//
// Save the global client info
//
if ( pStartRouterData->pInterfaceInfo == NULL )
{
gblRouterManagers[dwIndex].pDefaultClientInterface = NULL;
gblRouterManagers[dwIndex].dwDefaultClientInterfaceSize = 0;
}
else
{
LPBYTE lpData = LOCAL_ALLOC(LPTR,pStartRouterData->dwInterfaceInfoSize);
if ( lpData == NULL )
{
if ( pStartRouterData->pInterfaceInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pInterfaceInfo );
}
if ( pStartRouterData->pGlobalInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pGlobalInfo );
}
LOCAL_FREE( pStartRouterData );
return;
}
CopyMemory( lpData,
pStartRouterData->pInterfaceInfo,
pStartRouterData->dwInterfaceInfoSize );
gblRouterManagers[dwIndex].pDefaultClientInterface = lpData;
gblRouterManagers[dwIndex].dwDefaultClientInterfaceSize
= pStartRouterData->dwInterfaceInfoSize;
}
gblRouterManagers[dwIndex].fIsRunning = TRUE;
gblDIMConfigInfo.dwNumRouterManagers++;
//
// Register all interfaces with the router manager
//
AddInterfacesToRouterManager( NULL, pStartRouterData->dwTransportId );
//
// Notify router manager that all interfaces have been added to the
// router
//
gblRouterManagers[dwIndex].DdmRouterIf.RouterBootComplete();
if ( gblDIMConfigInfo.dwRouterRole != ROUTER_ROLE_LAN )
{
DWORD (*DDMTransportCreate)( DWORD ) =
(DWORD(*)( DWORD ))GetDDMEntryPoint("DDMTransportCreate");
if(NULL == DDMTransportCreate)
{
return ;
}
DDMTransportCreate( pStartRouterData->dwTransportId );
}
//
// We can only make this call while not holding the interface table
// lock
//
DIMTRACE( "Setting router attributes in the identity object" );
RouterIdentityObjectUpdateAttributes( FALSE, FALSE );
if ( pStartRouterData->pInterfaceInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pInterfaceInfo );
}
if ( pStartRouterData->pGlobalInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pGlobalInfo );
}
LOCAL_FREE( pStartRouterData );
}
//**
//
// Call: RRouterInterfaceTransportCreate
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description:
//
DWORD
RRouterInterfaceTransportCreate(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwTransportId,
IN LPWSTR lpwsTransportName,
IN PDIM_INTERFACE_CONTAINER pInfoStruct,
IN LPWSTR lpwsDLLPath
)
{
DWORD dwAccessStatus = 0;
DWORD dwRetCode = NO_ERROR;
DWORD dwIndex = gblDIMConfigInfo.dwNumRouterManagers;
START_ROUTER_DATA * pStartRouterData = NULL;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( GetTransportIndex( dwTransportId ) != (DWORD) -1 )
{
return( ERROR_PROTOCOL_ALREADY_INSTALLED );
}
if ( ( dwTransportId == PID_IP ) || ( dwTransportId == PID_IPX ) )
{
DWORD cbSize = 0;
WCHAR * pDllExpandedPath = NULL;
//
// Replace the %SystemRoot% with the actual path.
//
cbSize = ExpandEnvironmentStrings( lpwsDLLPath, NULL, 0 );
if ( cbSize == 0 )
{
return( GetLastError() );
}
else
{
cbSize *= sizeof( WCHAR );
}
pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) );
if ( pDllExpandedPath == (LPWSTR)NULL )
{
return( GetLastError() );
}
cbSize = ExpandEnvironmentStrings( lpwsDLLPath,
pDllExpandedPath,
cbSize );
if ( cbSize == 0 )
{
LOCAL_FREE( pDllExpandedPath );
return( GetLastError() );
}
//
// Load the DLL
//
gblRouterManagers[dwIndex].hModule = LoadLibrary( pDllExpandedPath );
LOCAL_FREE( pDllExpandedPath );
if ( gblRouterManagers[dwIndex].hModule == NULL )
{
return( GetLastError() );
}
pStartRouterData = LOCAL_ALLOC( LPTR, sizeof( START_ROUTER_DATA ) );
if ( pStartRouterData == NULL )
{
return( GetLastError() );
}
pStartRouterData->dwTransportId = dwTransportId;
pStartRouterData->dwInterfaceInfoSize = pInfoStruct->dwInterfaceInfoSize;
if ( pStartRouterData->dwInterfaceInfoSize != 0 )
{
pStartRouterData->pInterfaceInfo = LOCAL_ALLOC( LPTR,
pStartRouterData->dwInterfaceInfoSize );
if ( pStartRouterData->pInterfaceInfo == NULL )
{
LOCAL_FREE( pStartRouterData );
return( GetLastError() );
}
else
{
CopyMemory( pStartRouterData->pInterfaceInfo,
pInfoStruct->pInterfaceInfo,
pInfoStruct->dwInterfaceInfoSize );
}
}
pStartRouterData->dwGlobalInfoSize = pInfoStruct->dwGlobalInfoSize;
if ( pStartRouterData->dwGlobalInfoSize != 0 )
{
pStartRouterData->pGlobalInfo = LOCAL_ALLOC( LPTR,
pStartRouterData->dwGlobalInfoSize );
if ( pStartRouterData->pGlobalInfo == NULL )
{
if ( pStartRouterData->pInterfaceInfo != NULL )
{
LOCAL_FREE( pStartRouterData->pInterfaceInfo );
}
LOCAL_FREE( pStartRouterData );
return( GetLastError() );
}
else
{
CopyMemory( pStartRouterData->pGlobalInfo,
pInfoStruct->pGlobalInfo,
pInfoStruct->dwGlobalInfoSize );
}
}
//
// Schedule this for 15 seconds after returning from this call since setup
// may have a ways to go to complete doing all its installation.
// This is a low risk fix to
//
RtlQueueWorkItem( DoStartRouter, pStartRouterData, WT_EXECUTEDEFAULT );
}
return( NO_ERROR );
}
//**
//
// Call: RRouterInterfaceTransportSetGlobalInfo
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_UNKNOWN_PROTOCOL_ID
// non-zero returns from SetGlobalInfo
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceTransportSetGlobalInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwTransportId,
IN PDIM_INTERFACE_CONTAINER pInfoStruct
)
{
LPBYTE lpData;
DWORD dwAccessStatus = 0;
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex = GetTransportIndex( dwTransportId );
BOOL fGlobalDataUpdated = FALSE;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( pInfoStruct->pGlobalInfo != NULL )
{
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.SetGlobalInfo(
pInfoStruct->pGlobalInfo );
if ( dwRetCode != NO_ERROR )
{
break;
}
//
// Update router identity object since we may be adding or
// removing a routing protocol
//
fGlobalDataUpdated = TRUE;
}
if ( pInfoStruct->pInterfaceInfo != NULL )
{
lpData=gblRouterManagers[dwTransportIndex].pDefaultClientInterface;
if ( lpData != NULL )
{
LOCAL_FREE( lpData );
}
lpData = LOCAL_ALLOC( LPTR, pInfoStruct->dwInterfaceInfoSize );
if ( lpData == NULL )
{
dwRetCode = GetLastError();
break;
}
CopyMemory( lpData,
pInfoStruct->pInterfaceInfo,
pInfoStruct->dwInterfaceInfoSize );
gblRouterManagers[dwTransportIndex].pDefaultClientInterface=lpData;
gblRouterManagers[dwTransportIndex].dwDefaultClientInterfaceSize
= pInfoStruct->dwInterfaceInfoSize;
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
if ( ( dwRetCode == NO_ERROR ) && ( fGlobalDataUpdated ) )
{
//
// We can only make this call while not holding the interface table
// lock
//
RouterIdentityObjectUpdateAttributes( FALSE, FALSE );
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"SetGlobalInfo returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceTransportGetGlobalInfo
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_UNKNOWN_PROTOCOL_ID
// non-zero returns from GetGlobalInfo
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceTransportGetGlobalInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwTransportId,
IN PDIM_INTERFACE_CONTAINER pInfoStruct
)
{
DWORD dwAccessStatus = 0;
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex = GetTransportIndex( dwTransportId );
ULONG ulNumAttempts;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( pInfoStruct->fGetGlobalInfo )
{
ulNumAttempts = 0;
pInfoStruct->pGlobalInfo = NULL;
do
{
//
// The first iteration should get the size
// The second iteration should get the info.
// iteration 3 is only required if the
// size of the info. changes between first and
// second iteration.
// of course the size can change between iteration
// 2 and 3 and so on. So we try MAX_GET_INFO_RETRIES
// many times and quit if we still have not
// successfully retrieved the info.
//
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.GetGlobalInfo(
pInfoStruct->pGlobalInfo,
&(pInfoStruct->dwGlobalInfoSize) );
TracePrintfExA(
gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"GetGlobalInfo: Transport %d requires size %d, result %d",
dwTransportIndex, pInfoStruct->dwGlobalInfoSize,
dwRetCode
);
if ( dwRetCode != ERROR_INSUFFICIENT_BUFFER )
{
break;
}
//
// release previous allocation
//
if ( ulNumAttempts )
{
MIDL_user_free( pInfoStruct->pGlobalInfo );
pInfoStruct-> pGlobalInfo = NULL;
}
if ( pInfoStruct->dwGlobalInfoSize > 0 )
{
pInfoStruct->pGlobalInfo =
MIDL_user_allocate( pInfoStruct->dwGlobalInfoSize );
if ( pInfoStruct->pGlobalInfo == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
}
else
{
break;
}
ulNumAttempts++;
} while ( (dwRetCode == ERROR_INSUFFICIENT_BUFFER) &&
(ulNumAttempts < MAX_GET_INFO_RETRIES) );
}
if ( dwRetCode != NO_ERROR )
{
break;
}
if ((gblRouterManagers[dwTransportIndex].dwDefaultClientInterfaceSize>0)
&& ( pInfoStruct->fGetInterfaceInfo ) )
{
pInfoStruct->dwInterfaceInfoSize =
gblRouterManagers[dwTransportIndex].dwDefaultClientInterfaceSize;
pInfoStruct->pInterfaceInfo =
MIDL_user_allocate(pInfoStruct->dwInterfaceInfoSize);
if ( pInfoStruct->pInterfaceInfo == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
CopyMemory(
pInfoStruct->pInterfaceInfo,
gblRouterManagers[dwTransportIndex].pDefaultClientInterface,
pInfoStruct->dwInterfaceInfoSize );
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"GetGlobalInfo returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: InterfaceAjustVLSPointers
//
// Returns: none
//
// Description: Adjusts pointers in variable length structures
// dealing with interface info
//
DWORD
InterfaceAjustVLSPointers (
DWORD dwLevel,
LPBYTE lpbBuffer)
{
if ( dwLevel == 1 )
{
MPRI_INTERFACE_1 * pIf1 = (MPRI_INTERFACE_1*)lpbBuffer;
if ( pIf1->dwDialoutHoursRestrictionOffset )
{
pIf1->dwDialoutHoursRestrictionOffset = sizeof(MPRI_INTERFACE_1);
}
}
else if ( dwLevel == 2 )
{
MPRI_INTERFACE_2 * pIf2 = (MPRI_INTERFACE_2*)lpbBuffer;
DWORD dwOffset = 0;
// Adjust the custom auth data pointer
//
dwOffset += sizeof(MPRI_INTERFACE_2);
if ( pIf2->dwCustomAuthDataSize )
{
pIf2->dwCustomAuthDataOffset = dwOffset;
}
// Adjust the alternates list pointer
//
dwOffset += pIf2->dwCustomAuthDataSize;
if ( pIf2->dwAlternatesOffset )
{
pIf2->dwAlternatesOffset = dwOffset;
}
}
return NO_ERROR;
}
//**
//
// Call: GetMprInterface0Data
//
// Returns: none
//
// Description: Given a pointer to an interface object will fill an
// MPR_INTERFACE_0 structure appropriately.
//
VOID
GetMprInterface0Data(
IN ROUTER_INTERFACE_OBJECT * pIfObject,
OUT MPRI_INTERFACE_0 * pMprIf0
)
{
wcscpy( pMprIf0->wszInterfaceName, pIfObject->lpwsInterfaceName );
pMprIf0->dwIfType = pIfObject->IfType;
pMprIf0->dwInterface = PtrToUlong(pIfObject->hDIMInterface);
pMprIf0->dwLastError = pIfObject->dwLastError;
pMprIf0->fEnabled = ( pIfObject->fFlags & IFFLAG_ENABLED );
pMprIf0->fUnReachabilityReasons =
( pIfObject->fFlags & IFFLAG_OUT_OF_RESOURCES )
? MPR_INTERFACE_OUT_OF_RESOURCES : 0;
if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
{
pMprIf0->fUnReachabilityReasons |= MPR_INTERFACE_ADMIN_DISABLED;
}
if ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_PAUSED )
{
pMprIf0->fUnReachabilityReasons |= MPR_INTERFACE_SERVICE_PAUSED;
}
if ( pIfObject->fFlags & IFFLAG_CONNECTION_FAILURE )
{
pMprIf0->fUnReachabilityReasons |= MPR_INTERFACE_CONNECTION_FAILURE;
}
if ( pIfObject->fFlags & IFFLAG_DIALOUT_HOURS_RESTRICTION )
{
pMprIf0->fUnReachabilityReasons |=
MPR_INTERFACE_DIALOUT_HOURS_RESTRICTION;
}
if ( pIfObject->fFlags & IFFLAG_NO_MEDIA_SENSE )
{
pMprIf0->fUnReachabilityReasons |= MPR_INTERFACE_NO_MEDIA_SENSE;
}
switch( pIfObject->State )
{
case RISTATE_CONNECTED:
pMprIf0->dwConnectionState = ROUTER_IF_STATE_CONNECTED;
break;
case RISTATE_DISCONNECTED:
if ( pMprIf0->fUnReachabilityReasons != 0 )
{
pMprIf0->dwConnectionState = ROUTER_IF_STATE_UNREACHABLE;
}
else
{
pMprIf0->dwConnectionState = ROUTER_IF_STATE_DISCONNECTED;
}
break;
case RISTATE_CONNECTING:
pMprIf0->dwConnectionState = ROUTER_IF_STATE_CONNECTING;
break;
}
}
//**
//
// Call: GetMprInterfaceData
//
// Returns: none
//
// Description: Given a pointer to an interface object will fill an
// MPRI_INTERFACE_* structure appropriately.
//
LPBYTE
GetMprInterfaceData(
IN ROUTER_INTERFACE_OBJECT * pIfObject,
IN DWORD dwLevel,
OUT LPDWORD lpdwcbSizeOfData
)
{
DWORD cbDialoutHoursRestriction = 0;
DWORD dwErr;
MPRI_INTERFACE_0 * pMprIf0 = NULL;
MPRI_INTERFACE_1 * pIf1 = NULL;
LPBYTE pInterfaceData = NULL;
HANDLE hEntry = NULL;
switch ( dwLevel )
{
// Basic
//
case 0:
*lpdwcbSizeOfData = sizeof( MPRI_INTERFACE_0 );
dwErr = NO_ERROR;
break;
// Basic plus dialout hours restriction
//
case 1:
*lpdwcbSizeOfData = sizeof( MPRI_INTERFACE_1 );
if ( pIfObject->lpwsDialoutHoursRestriction != NULL )
{
cbDialoutHoursRestriction =
GetSizeOfDialoutHoursRestriction(
pIfObject->lpwsDialoutHoursRestriction);
*lpdwcbSizeOfData += cbDialoutHoursRestriction;
}
dwErr = NO_ERROR;
break;
// Basic plus router phonebook entry info
//
case 2:
dwErr = RpbkOpenEntry(pIfObject, &hEntry);
if (dwErr == NO_ERROR)
{
dwErr = RpbkEntryToIfDataSize(
hEntry,
dwLevel,
lpdwcbSizeOfData);
}
break;
}
if (dwErr != NO_ERROR)
{
return( NULL );
}
do
{
// Allocate the return value
pInterfaceData = MIDL_user_allocate( *lpdwcbSizeOfData );
if ( pInterfaceData == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
//
// Add any appropriate information
//
switch ( dwLevel )
{
case 0:
GetMprInterface0Data( pIfObject, (MPRI_INTERFACE_0 *)pInterfaceData );
break;
case 1:
GetMprInterface0Data( pIfObject, (MPRI_INTERFACE_0 *)pInterfaceData );
pIf1 = (MPRI_INTERFACE_1*)pInterfaceData;
if ( pIfObject->lpwsDialoutHoursRestriction != NULL )
{
CopyMemory( pIf1 + 1,
pIfObject->lpwsDialoutHoursRestriction,
cbDialoutHoursRestriction );
pIf1->dwDialoutHoursRestrictionOffset = TRUE;
}
else
{
pIf1->dwDialoutHoursRestrictionOffset = 0;
}
break;
case 2:
GetMprInterface0Data( pIfObject, (MPRI_INTERFACE_0 *)pInterfaceData );
dwErr = RpbkEntryToIfData(
hEntry,
dwLevel,
pInterfaceData );
break;
}
} while (FALSE);
// Cleanup
{
if ( dwErr != NO_ERROR )
{
if ( pInterfaceData )
{
MIDL_user_free( pInterfaceData );
}
}
if ( hEntry )
{
RpbkCloseEntry( hEntry );
}
}
return( pInterfaceData );
}
//**
//
// Call: GetMprInterfaceData
//
// Returns: none
//
// Description: Given a pointer to an interface object will fill an
// MPR_INTERFACE_* structure appropriately.
//
DWORD
GetMprInterfaceDeviceData(
IN ROUTER_INTERFACE_OBJECT * pIfObject,
IN DWORD dwIndex,
IN DWORD dwLevel,
OUT LPDWORD lpdwcbSizeOfData,
OUT LPBYTE* lplpbReturn
)
{
DWORD dwErr = NO_ERROR;
LPBYTE pDevData = NULL;
HANDLE hSubEntry = NULL;
*lplpbReturn = NULL;
switch ( dwLevel )
{
// Basic
//
case 0:
*lpdwcbSizeOfData = sizeof( MPR_DEVICE_0 );
dwErr = NO_ERROR;
break;
// Basic plus phone numbers
//
case 1:
dwErr = RpbkOpenSubEntry(pIfObject, dwIndex, &hSubEntry);
if (dwErr == NO_ERROR)
{
dwErr = RpbkSubEntryToDevDataSize(
hSubEntry,
dwLevel,
lpdwcbSizeOfData);
}
break;
}
if (dwErr != NO_ERROR)
{
return( dwErr );
}
do
{
// Allocate the return value
//
pDevData = MIDL_user_allocate( *lpdwcbSizeOfData );
if ( pDevData == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
//
// Add any appropriate information
//
switch ( dwLevel )
{
case 0:
case 1:
dwErr = RpbkSubEntryToDevData(
hSubEntry,
dwLevel,
pDevData );
break;
}
} while (FALSE);
// Cleanup
{
if ( hSubEntry )
{
RpbkCloseSubEntry( hSubEntry );
}
if ( dwErr != NO_ERROR )
{
if ( pDevData )
{
MIDL_user_free( pDevData );
}
}
else
{
*lplpbReturn = pDevData;
}
}
return( dwErr );
}
//**
//
// Call: RRouterInterfaceCreate
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_NOT_SUPPORTED
//
// Description: Creates an interface with DIM.
//
DWORD
RRouterInterfaceCreate(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN LPDWORD phInterface
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject;
DWORD IfState;
DWORD dwRetCode = NO_ERROR;
LPWSTR lpwsDialoutHoursRestriction = NULL;
BOOL fLANInterfaceAdded = FALSE;
MPRI_INTERFACE_0 * pMprIf0 =
(MPRI_INTERFACE_0*)pInfoStruct->pBuffer;
MPRI_INTERFACE_1 * pMprIf1 =
(MPRI_INTERFACE_1*)pInfoStruct->pBuffer;
MPRI_INTERFACE_2 * pMprIf2 =
(MPRI_INTERFACE_2*)pInfoStruct->pBuffer;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( ( (int) dwLevel < 0 ) || ( dwLevel > 2 ) )
{
return( ERROR_NOT_SUPPORTED );
}
if ( pMprIf0->dwIfType == ROUTER_IF_TYPE_TUNNEL1)
{
return( ERROR_NOT_SUPPORTED );
}
//
// Adjust the given buffer for any pointers to
// variable length data.
//
InterfaceAjustVLSPointers ( dwLevel, pInfoStruct->pBuffer );
if ( ( pMprIf0->dwIfType == ROUTER_IF_TYPE_DEDICATED ) ||
( pMprIf0->dwIfType == ROUTER_IF_TYPE_INTERNAL ) ||
( pMprIf0->dwIfType == ROUTER_IF_TYPE_LOOPBACK ) ||
( pMprIf0->dwIfType == ROUTER_IF_TYPE_TUNNEL1 ) )
{
IfState = RISTATE_CONNECTED;
if ( !pMprIf0->fEnabled )
{
return( ERROR_INVALID_PARAMETER );
}
//
// Update router identity object since we are adding a LAN interface
//
fLANInterfaceAdded = TRUE;
}
else if ( ( pMprIf0->dwIfType == ROUTER_IF_TYPE_CLIENT ) ||
( pMprIf0->dwIfType == ROUTER_IF_TYPE_HOME_ROUTER ) ||
( pMprIf0->dwIfType == ROUTER_IF_TYPE_FULL_ROUTER ) )
{
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
{
return( ERROR_DDM_NOT_RUNNING );
}
else
{
IfState = RISTATE_DISCONNECTED;
}
}
else
{
return( ERROR_INVALID_PARAMETER );
}
if ( dwLevel == 1 )
{
if ( pMprIf1->dwDialoutHoursRestrictionOffset != 0 )
{
DWORD cbDialoutHoursRestriction;
cbDialoutHoursRestriction =
GetSizeOfDialoutHoursRestriction((LPWSTR)(pMprIf1 + 1));
DIMTRACE1(
"Creating l1 interface with %d bytes of dohr",
cbDialoutHoursRestriction);
lpwsDialoutHoursRestriction =
LOCAL_ALLOC( LPTR, cbDialoutHoursRestriction );
if ( lpwsDialoutHoursRestriction == NULL )
{
return( GetLastError() );
}
}
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( pMprIf0->dwIfType != ROUTER_IF_TYPE_CLIENT )
{
//
// Check for duplicates if we are not adding a client interface
//
pIfObject = IfObjectGetPointerByName( pMprIf0->wszInterfaceName,
FALSE );
if ( pIfObject != NULL )
{
dwRetCode = ERROR_INTERFACE_ALREADY_EXISTS;
break;
}
}
//
// If phonebook information is being specified, set it
// before continuing
//
if (dwLevel == 2)
{
dwRetCode = RpbkSetEntry(dwLevel, (LPBYTE)pMprIf2);
if (dwRetCode != NO_ERROR)
{
break;
}
}
pIfObject = IfObjectAllocateAndInit(
pMprIf0->wszInterfaceName,
IfState,
pMprIf0->dwIfType,
(HCONN)0,
pMprIf0->fEnabled,
600,
21600,
lpwsDialoutHoursRestriction );
if ( pIfObject == NULL )
{
dwRetCode = GetLastError();
break;
}
if ( ( dwRetCode = IfObjectInsertInTable( pIfObject ) ) != NO_ERROR )
{
LOCAL_FREE( pIfObject );
break;
}
*phInterface = PtrToUlong(pIfObject->hDIMInterface);
if ( lpwsDialoutHoursRestriction != NULL )
{
VOID (*IfObjectSetDialoutHoursRestriction)(
ROUTER_INTERFACE_OBJECT * ) =
(VOID(*)( ROUTER_INTERFACE_OBJECT *))
GetDDMEntryPoint("IfObjectSetDialoutHoursRestriction");
//
// Set dialout hours restriction if there was one
//
IfObjectSetDialoutHoursRestriction( pIfObject );
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceCreate returned %d", dwRetCode );
if ( dwRetCode != NO_ERROR )
{
if ( lpwsDialoutHoursRestriction != NULL )
{
//
// If there was some error then free this memory
//
LOCAL_FREE( lpwsDialoutHoursRestriction );
}
}
else
{
if ( fLANInterfaceAdded )
{
//
// Can only call this API while not holding the interface lock
//
RouterIdentityObjectUpdateAttributes( FALSE, FALSE );
}
}
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceGetInfo
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_NOT_SUPPORTED
//
// Description: Gets information about a DIM interface.
//
DWORD
RRouterInterfaceGetInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD hInterface
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject;
DWORD dwRetCode = NO_ERROR;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( ( (int) dwLevel < 0 ) || ( dwLevel > 2 ) )
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface)) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
// pmay: 274487
//
// Validate the type of the interface against the level
//
if ( ( dwLevel == 2 ) &&
( pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER ) )
{
dwRetCode = ERROR_INVALID_LEVEL;
break;
}
pInfoStruct->pBuffer = GetMprInterfaceData(
pIfObject,
dwLevel,
&(pInfoStruct->dwBufferSize) );
if ( pInfoStruct->pBuffer == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceGetInfo returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceSetInfo
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_NOT_SUPPORTED
//
// Description: Sets interface configuration information
//
DWORD
RRouterInterfaceSetInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD hInterface
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject;
DWORD IfState;
DWORD dwRetCode = NO_ERROR;
BOOL fNotify = FALSE;
DWORD dwIndex;
MPRI_INTERFACE_0 * pMprIf0 =
(MPRI_INTERFACE_0*)pInfoStruct->pBuffer;
MPRI_INTERFACE_1 * pMprIf1 =
(MPRI_INTERFACE_1*)pInfoStruct->pBuffer;
MPRI_INTERFACE_2 * pMprIf2 =
(MPRI_INTERFACE_2*)pInfoStruct->pBuffer;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( ( (int) dwLevel < 0 ) || ( dwLevel > 2 ) )
{
return( ERROR_NOT_SUPPORTED );
}
//
// Adjust the given buffer for any pointers to
// variable length data.
//
InterfaceAjustVLSPointers ( dwLevel, pInfoStruct->pBuffer );
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface)) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
if ( ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED ) ||
( pIfObject->IfType == ROUTER_IF_TYPE_TUNNEL1 ) ||
( pIfObject->IfType == ROUTER_IF_TYPE_INTERNAL ) )
{
if ( !pMprIf0->fEnabled )
{
dwRetCode = ERROR_INVALID_PARAMETER;
}
//
// Nothing can be set for these interfaces
//
break;
}
if ( pMprIf0->fEnabled )
{
if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
{
pIfObject->fFlags |= IFFLAG_ENABLED;
fNotify = TRUE;
}
}
else
{
if ( pIfObject->fFlags & IFFLAG_ENABLED )
{
pIfObject->fFlags &= ~IFFLAG_ENABLED;
fNotify = TRUE;
}
if ( pIfObject->State != RISTATE_DISCONNECTED )
{
fNotify = FALSE;
}
}
if ( fNotify )
{
VOID (*IfObjectNotifyOfReachabilityChange)(
ROUTER_INTERFACE_OBJECT *,
BOOL,
UNREACHABILITY_REASON ) =
(VOID(*)( ROUTER_INTERFACE_OBJECT *,
BOOL,
UNREACHABILITY_REASON ))
GetDDMEntryPoint("IfObjectNotifyOfReachabilityChange");
if(NULL != IfObjectNotifyOfReachabilityChange)
{
IfObjectNotifyOfReachabilityChange( pIfObject,
pMprIf0->fEnabled,
INTERFACE_DISABLED );
}
}
//
// Check level 1 values
//
if ( dwLevel == 1 )
{
VOID (*IfObjectSetDialoutHoursRestriction)(
ROUTER_INTERFACE_OBJECT * ) =
(VOID(*)( ROUTER_INTERFACE_OBJECT *))
GetDDMEntryPoint("IfObjectSetDialoutHoursRestriction");
if ( pMprIf1->dwDialoutHoursRestrictionOffset == 0 )
{
if ( pIfObject->lpwsDialoutHoursRestriction != NULL )
{
LOCAL_FREE( pIfObject->lpwsDialoutHoursRestriction );
pIfObject->lpwsDialoutHoursRestriction = NULL;
IfObjectSetDialoutHoursRestriction( pIfObject );
}
}
else
{
DWORD cbDialoutHoursRestriction =
GetSizeOfDialoutHoursRestriction(
(LPWSTR)(pMprIf1 + 1) );
if ( pIfObject->lpwsDialoutHoursRestriction != NULL )
{
//
// Free currently allocated memory for dialout hours
//
LOCAL_FREE( pIfObject->lpwsDialoutHoursRestriction );
pIfObject->lpwsDialoutHoursRestriction = NULL;
}
DIMTRACE1(
"Setting info on l1 interface. %d bytes dohr",
cbDialoutHoursRestriction);
pIfObject->lpwsDialoutHoursRestriction =
LOCAL_ALLOC( LPTR, cbDialoutHoursRestriction );
if ( pIfObject->lpwsDialoutHoursRestriction == NULL )
{
dwRetCode = GetLastError();
break;
}
CopyMemory( pIfObject->lpwsDialoutHoursRestriction,
(LPBYTE)(pMprIf1 + 1),
cbDialoutHoursRestriction );
IfObjectSetDialoutHoursRestriction( pIfObject );
}
}
//
// Check level 2 values
//
else if ( dwLevel == 2 )
{
if (pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER)
{
dwRetCode = ERROR_INVALID_PARAMETER;
}
else
{
dwRetCode = RpbkSetEntry(dwLevel, (LPBYTE)pMprIf2);
}
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceSetInfo returned %d", dwRetCode );
return( dwRetCode );
}
DWORD
RRouterInterfaceDeviceGetInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD dwIndex,
IN DWORD hInterface
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject;
DWORD dwRetCode = NO_ERROR;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( ( (int) dwLevel < 0 ) || ( dwLevel > 1 ) )
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface)) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
dwRetCode = GetMprInterfaceDeviceData(
pIfObject,
dwIndex,
dwLevel,
&(pInfoStruct->dwBufferSize),
&(pInfoStruct->pBuffer));
if ( dwRetCode != NO_ERROR )
{
if ( dwRetCode == ERROR_CANNOT_FIND_PHONEBOOK_ENTRY )
{
dwRetCode = ERROR_DEV_NOT_EXIST;
}
break;
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceDeviceGetInfo returned %d", dwRetCode );
return( dwRetCode );
}
DWORD
RRouterInterfaceDeviceSetInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD dwIndex,
IN DWORD hInterface
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject;
DWORD dwRetCode = NO_ERROR;
MPR_DEVICE_0 * pDev0 =
(MPR_DEVICE_0*)pInfoStruct->pBuffer;
MPR_DEVICE_1 * pDev1 =
(MPR_DEVICE_1*)pInfoStruct->pBuffer;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( ( (int) dwLevel < 0 ) || ( dwLevel > 1 ) )
{
return( ERROR_NOT_SUPPORTED );
}
// Adjust the variable-length structure pointers
//
if ( dwLevel == 1 )
{
if ( pDev1->szAlternates )
{
pDev1->szAlternates = (PWCHAR)(pDev1 + 1);
}
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface)) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// Set the subentry
//
if (pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER)
{
dwRetCode = ERROR_INVALID_PARAMETER;
}
else
{
dwRetCode = RpbkSetSubEntry(
pIfObject->lpwsInterfaceName,
dwIndex,
dwLevel,
pInfoStruct->pBuffer);
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceDeviceSetInfo returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceGetHandle
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
//
// Description:
//
DWORD
RRouterInterfaceGetHandle(
IN MPR_SERVER_HANDLE hMprServer,
IN LPWSTR lpwsInterfaceName,
IN LPDWORD phInterface,
IN DWORD fIncludeClientInterfaces
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
DWORD dwRetCode = NO_ERROR;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
pIfObject = IfObjectGetPointerByName( lpwsInterfaceName,
fIncludeClientInterfaces );
if ( pIfObject == NULL )
{
dwRetCode = ERROR_NO_SUCH_INTERFACE;
break;
}
*phInterface = PtrToUlong(pIfObject->hDIMInterface);
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceDelete
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
//
// Description: Deletes and interface from the DIM database.
// work.
//
DWORD
RRouterInterfaceDelete(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hInterface
)
{
DWORD dwAccessStatus;
DWORD dwTransportIndex;
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
DWORD dwRetCode = NO_ERROR;
BOOL fLANInterfaceRemoved = FALSE;
BOOL fDeletePbkEntry = FALSE;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface)) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// If this is a demand dial dynamic interface then we cannot delete
// it if it is connected.
//
if ( ( pIfObject->IfType == ROUTER_IF_TYPE_CLIENT ) ||
( pIfObject->IfType == ROUTER_IF_TYPE_HOME_ROUTER ) ||
( pIfObject->IfType == ROUTER_IF_TYPE_FULL_ROUTER ) )
{
if ( pIfObject->State != RISTATE_DISCONNECTED )
{
dwRetCode = ERROR_INTERFACE_CONNECTED;
break;
}
fDeletePbkEntry = TRUE;
//
// Remove credentials for this interface if they were set.
//
MprAdminInterfaceSetCredentials( NULL,
pIfObject->lpwsInterfaceName,
NULL,
NULL,
NULL );
}
else
{
//
// Update router identity object since we are removing a LAN
// interface
//
fLANInterfaceRemoved = TRUE;
}
//
// Delete any transport interfaces that might still be around
//
for ( dwTransportIndex = 0;
dwTransportIndex < gblDIMConfigInfo.dwNumRouterManagers;
dwTransportIndex++ )
{
if ( pIfObject->Transport[dwTransportIndex].hInterface !=
INVALID_HANDLE_VALUE )
{
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.DeleteInterface(
pIfObject->Transport[dwTransportIndex].hInterface );
if ( dwRetCode != NO_ERROR )
{
break;
}
pIfObject->Transport[dwTransportIndex].hInterface
= INVALID_HANDLE_VALUE;
pIfObject->Transport[dwTransportIndex].fState = 0;
}
}
if ( fDeletePbkEntry )
{
RpbkDeleteEntry( pIfObject->lpwsInterfaceName );
}
IfObjectRemove( (HANDLE)UlongToPtr(hInterface) );
} while ( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
if ( ( dwRetCode == NO_ERROR ) && ( fLANInterfaceRemoved ) )
{
//
// Can only call this API while not holding the interface lock
//
RouterIdentityObjectUpdateAttributes( FALSE, FALSE );
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"DeleteInterface returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceTransportRemove
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceTransportRemove(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hInterface,
IN DWORD dwTransportId
)
{
DWORD dwAccessStatus;
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex
= GetTransportIndex( dwTransportId );
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface)) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// If this is a demand dial dynamic interface then we cannot delete
// it if it is connected.
//
if ( ( pIfObject->IfType == ROUTER_IF_TYPE_CLIENT ) ||
( pIfObject->IfType == ROUTER_IF_TYPE_HOME_ROUTER ) ||
( pIfObject->IfType == ROUTER_IF_TYPE_FULL_ROUTER ) )
{
if ( pIfObject->State == RISTATE_CONNECTED )
{
dwRetCode = ERROR_INTERFACE_CONNECTED;
break;
}
}
//
// Remove the transport interface.
//
if ( pIfObject->Transport[dwTransportIndex].hInterface
!= INVALID_HANDLE_VALUE )
{
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.DeleteInterface(
pIfObject->Transport[dwTransportIndex].hInterface );
if ( dwRetCode == NO_ERROR )
{
pIfObject->Transport[dwTransportIndex].hInterface
= INVALID_HANDLE_VALUE;
}
}
else
{
dwRetCode = ERROR_NO_SUCH_INTERFACE;
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"RemoveInterface returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceTransportGetInfo
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_UNKNOWN_PROTOCOL_ID
// ERROR_INVALID_HANDLE
// non-zero returns from GetInterfaceInfo
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceTransportGetInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hInterface,
IN DWORD dwTransportId,
IN DIM_INTERFACE_CONTAINER * pInfoStruct
)
{
DWORD dwAccessStatus = 0;
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex = GetTransportIndex( dwTransportId );
ULONG ulNumAttempts;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
(HANDLE) UlongToPtr(hInterface ))) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// If the interface has not been added for this protocol
//
if ( pIfObject->Transport[dwTransportIndex].hInterface
== INVALID_HANDLE_VALUE )
{
dwRetCode = ERROR_NO_SUCH_INTERFACE;
break;
}
if ( pInfoStruct->fGetInterfaceInfo )
{
ulNumAttempts = 0;
pInfoStruct->pInterfaceInfo = NULL;
do
{
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.GetInterfaceInfo(
pIfObject->Transport[dwTransportIndex].hInterface,
pInfoStruct->pInterfaceInfo,
&(pInfoStruct->dwInterfaceInfoSize) );
TracePrintfExA(
gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"GetInterfaceInfo: Transport %d requires size %d, result %d",
dwTransportIndex, pInfoStruct->dwInterfaceInfoSize,
dwRetCode
);
if ( dwRetCode != ERROR_INSUFFICIENT_BUFFER )
{
break;
}
//
// Release previous allocation
//
if ( ulNumAttempts )
{
MIDL_user_free( pInfoStruct->pInterfaceInfo );
pInfoStruct->pInterfaceInfo = NULL;
}
if ( pInfoStruct->dwInterfaceInfoSize > 0 )
{
pInfoStruct->pInterfaceInfo = MIDL_user_allocate(
pInfoStruct->dwInterfaceInfoSize);
if ( pInfoStruct->pInterfaceInfo == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
}
else
{
break;
}
ulNumAttempts++;
} while ( (dwRetCode == ERROR_INSUFFICIENT_BUFFER) &&
(ulNumAttempts < MAX_GET_INFO_RETRIES) );
}
} while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceGetInfo returned %d", dwRetCode );
if ( !pInfoStruct->fGetInterfaceInfo )
{
pInfoStruct->dwInterfaceInfoSize = 0;
}
if ( dwRetCode != NO_ERROR )
{
pInfoStruct->dwInterfaceInfoSize = 0;
}
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceTransportAdd
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_UNKNOWN_PROTOCOL_ID
// ERROR_INVALID_HANDLE
// non-zero returns from AddInterface
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceTransportAdd(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hInterface,
IN DWORD dwTransportId,
IN DIM_INTERFACE_CONTAINER * pInfoStruct
)
{
DWORD dwAccessStatus = 0;
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
DWORD dwRetCode = NO_ERROR;
DWORD dwIndex = GetTransportIndex( dwTransportId );
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface) )) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// If the handle to the interface is NULL, then we have to add the
// interface
//
if ( pIfObject->Transport[dwIndex].hInterface == INVALID_HANDLE_VALUE )
{
if (IsInterfaceRoleAcceptable(pIfObject, dwTransportId))
{
dwRetCode =
gblRouterManagers[dwIndex].DdmRouterIf.AddInterface(
pIfObject->lpwsInterfaceName,
pInfoStruct->pInterfaceInfo,
pIfObject->IfType,
pIfObject->hDIMInterface,
&pIfObject->Transport[dwIndex].hInterface);
if ( dwRetCode != NO_ERROR )
{
pIfObject->Transport[dwIndex].hInterface =
INVALID_HANDLE_VALUE;
}
else
{
if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) ||
( pIfObject->fFlags & IFFLAG_OUT_OF_RESOURCES ) ||
( gblDIMConfigInfo.ServiceStatus.dwCurrentState ==
SERVICE_PAUSED))
{
TracePrintfExA(
gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceTransportAdd: Set if to unreachable");
gblRouterManagers[dwIndex].DdmRouterIf.InterfaceNotReachable(
pIfObject->Transport[dwIndex].hInterface,
INTERFACE_DISABLED );
}
}
}
else
{
pIfObject->Transport[dwIndex].hInterface = INVALID_HANDLE_VALUE;
}
}
else
{
dwRetCode = ERROR_INTERFACE_ALREADY_EXISTS;
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceTransportAdd returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceTransportSetInfo
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_UNKNOWN_PROTOCOL_ID
// ERROR_INVALID_HANDLE
// non-zero returns from AddInterface or SetInterfaceInfo
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceTransportSetInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hInterface,
IN DWORD dwTransportId,
IN DIM_INTERFACE_CONTAINER * pInfoStruct
)
{
DWORD dwAccessStatus = 0;
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex = GetTransportIndex( dwTransportId );
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface))) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// If the handle to the interface is NULL, then we have to add the
// interface
//
if ( pIfObject->Transport[dwTransportIndex].hInterface
== INVALID_HANDLE_VALUE )
{
dwRetCode = ERROR_NO_SUCH_INTERFACE;
}
else
{
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.SetInterfaceInfo(
pIfObject->Transport[dwTransportIndex].hInterface,
pInfoStruct->pInterfaceInfo );
}
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceSetInfo returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceEnum
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
// ERROR_NOT_SUPPORTED
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceEnum(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN OUT PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD dwPreferedMaximumLength,
OUT LPDWORD lpdwEntriesRead,
OUT LPDWORD lpdwTotalEntries,
IN OUT LPDWORD lpdwResumeHandle OPTIONAL
)
{
DWORD dwAccessStatus;
PMPRI_INTERFACE_0 pInterface0 = NULL;
DWORD dwIfIndex = 0;
DWORD dwBucketIndex= 0;
PROUTER_INTERFACE_OBJECT pIfObject = NULL;
DWORD dwStartIndex = ( lpdwResumeHandle == NULL )
? 0 : *lpdwResumeHandle;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwLevel != 0 )
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
if ( gblInterfaceTable.dwNumTotalInterfaces < dwStartIndex )
{
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
return( ERROR_NO_MORE_ITEMS );
}
*lpdwTotalEntries = gblInterfaceTable.dwNumTotalInterfaces - dwStartIndex;
if ( dwPreferedMaximumLength != -1 )
{
*lpdwEntriesRead = dwPreferedMaximumLength /
sizeof( MPR_INTERFACE_0 );
if ( *lpdwEntriesRead > *lpdwTotalEntries )
{
*lpdwEntriesRead = *lpdwTotalEntries;
}
}
else
{
*lpdwEntriesRead = *lpdwTotalEntries;
}
pInfoStruct->dwBufferSize = *lpdwEntriesRead * sizeof( MPR_INTERFACE_0 );
pInfoStruct->pBuffer = MIDL_user_allocate( pInfoStruct->dwBufferSize );
if ( pInfoStruct->pBuffer == NULL )
{
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
pInfoStruct->dwBufferSize = 0;
return( ERROR_NOT_ENOUGH_MEMORY );
}
pInterface0 = (PMPRI_INTERFACE_0)pInfoStruct->pBuffer;
for ( dwBucketIndex = 0; dwBucketIndex < NUM_IF_BUCKETS; dwBucketIndex++ )
{
for( pIfObject = gblInterfaceTable.IfBucket[dwBucketIndex];
pIfObject != (ROUTER_INTERFACE_OBJECT *)NULL;
pIfObject = pIfObject->pNext )
{
//
// Check if this interface is within the range we need to copy
// from.
//
if ( ( dwIfIndex >= dwStartIndex ) &&
( dwIfIndex < ( dwStartIndex + *lpdwEntriesRead ) ) )
{
//
// Copy the info
//
GetMprInterface0Data( pIfObject, pInterface0 );
pInterface0++;
}
else if ( dwIfIndex >= (dwStartIndex+*lpdwEntriesRead) )
{
//
// Beyond the range so exit
//
if ( lpdwResumeHandle != NULL )
{
*lpdwResumeHandle = dwIfIndex;
}
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
return( ERROR_MORE_DATA );
}
dwIfIndex++;
}
}
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
return( NO_ERROR );
}
//**
//
// Call: RRouterInterfaceUpdateRoutes
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceUpdateRoutes(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hDimInterface,
IN DWORD dwPid,
IN ULONG_PTR hEvent,
IN DWORD dwCallersProcessId
)
{
DWORD dwAccessStatus;
PROUTER_INTERFACE_OBJECT pIfObject = NULL;
HANDLE hEventDuplicated;
HANDLE hEventToBeDuplicated;
HANDLE hClientProcess;
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex = GetTransportIndex( dwPid );
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
if ( hEvent == PtrToUlong(NULL) )
{
//
// This call is to be synchrnonous, create an event and block on
// it.
//
hEventToBeDuplicated = CreateEvent( NULL, FALSE, FALSE, NULL );
if ( hEventToBeDuplicated == NULL )
{
return( GetLastError() );
}
dwCallersProcessId = GetCurrentProcessId();
}
else
{
hEventToBeDuplicated = (HANDLE)hEvent;
}
//
// Get process handle of the caller of this API
//
hClientProcess = OpenProcess(
STANDARD_RIGHTS_REQUIRED | SPECIFIC_RIGHTS_ALL,
FALSE,
dwCallersProcessId);
if ( hClientProcess == NULL )
{
return( GetLastError() );
}
//
// Duplicate the handle to the event
//
if ( !DuplicateHandle( hClientProcess,
(HANDLE)hEventToBeDuplicated,
GetCurrentProcess(),
&hEventDuplicated,
0,
FALSE,
DUPLICATE_SAME_ACCESS ) )
{
CloseHandle( hClientProcess );
return( GetLastError() );
}
CloseHandle( hClientProcess );
//
// Validate the interface handle and check to see if it is connected
//
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hDimInterface))) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
if ( pIfObject->State != RISTATE_CONNECTED )
{
dwRetCode = ERROR_INTERFACE_NOT_CONNECTED;
break;
}
//
// Make sure the handle to the interface is NULL, then the interface
// has not yet been added to the transport.
//
if ( pIfObject->Transport[dwTransportIndex].hInterface
== INVALID_HANDLE_VALUE )
{
dwRetCode = ERROR_NO_SUCH_INTERFACE;
break;
}
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.UpdateRoutes(
pIfObject->Transport[dwTransportIndex].hInterface,
(HANDLE)hEventDuplicated );
} while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
if ( ( dwRetCode != NO_ERROR ) && ( dwRetCode != PENDING ) )
{
CloseHandle( hEventDuplicated );
}
if ( hEvent == PtrToUlong(NULL) )
{
if ( ( dwRetCode == NO_ERROR ) || ( dwRetCode == PENDING ) )
{
//
// Wait for this event to be signalled
//
if ( WaitForSingleObject( hEventToBeDuplicated, INFINITE ) ==
WAIT_FAILED )
{
dwRetCode = GetLastError();
}
}
CloseHandle( hEventToBeDuplicated );
if ( dwRetCode == PENDING )
{
dwRetCode = NO_ERROR;
}
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceUpdateRoutes returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceQueryUpdateResult
//
// Returns: NO_ERROR - Success
// ERROR_ACCESS_DENIED - FAILURE
//
//
// Description: Simply called the appropriate router manager to do the real
// work.
//
DWORD
RRouterInterfaceQueryUpdateResult(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hDimInterface,
IN DWORD dwPid,
IN LPDWORD pUpdateResult
)
{
DWORD dwAccessStatus;
DWORD dwRetCode = NO_ERROR;
PROUTER_INTERFACE_OBJECT pIfObject = NULL;
DWORD dwTransportIndex = GetTransportIndex( dwPid );
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwTransportIndex == (DWORD)-1 )
{
return( ERROR_UNKNOWN_PROTOCOL_ID );
}
//
// Validate the interface handle and check to see if it is connected
//
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hDimInterface))) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
if ( pIfObject->State != RISTATE_CONNECTED )
{
dwRetCode = ERROR_INTERFACE_NOT_CONNECTED;
break;
}
//
// Make sure the handle to the interface is NULL, then the interface
// has not yet been added to the transport.
//
if ( pIfObject->Transport[dwTransportIndex].hInterface
== INVALID_HANDLE_VALUE )
{
dwRetCode = ERROR_NO_SUCH_INTERFACE;
break;
}
dwRetCode =
gblRouterManagers[dwTransportIndex].DdmRouterIf.GetUpdateRoutesResult(
pIfObject->Transport[dwTransportIndex].hInterface,
pUpdateResult );
}while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"QueryUpdateResult returned %d", dwRetCode );
return( dwRetCode );
}
//**
//
// Call: RRouterInterfaceConnect
//
// Returns: ERROR_ACCESS_DENIED - The caller does not have sufficient priv.
// ERROR_DDM_NOT_RUNNING - This call cannot be made because DDM is
// not loaded
// non-zero returns from DDMAdminInterfaceConnect
//
// Description: Simply calles into DDM to do the work.
//
DWORD
RRouterInterfaceConnect(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hDimInterface,
IN ULONG_PTR hEvent,
IN DWORD fBlocking,
IN DWORD dwCallersProcessId
)
{
DWORD dwAccessStatus;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
{
return( ERROR_DDM_NOT_RUNNING );
}
else
{
DWORD (*DDMAdminInterfaceConnect)( HANDLE, HANDLE, BOOL, DWORD ) =
(DWORD(*)( HANDLE, HANDLE, BOOL, DWORD ) )
GetDDMEntryPoint("DDMAdminInterfaceConnect");
if(NULL == DDMAdminInterfaceConnect)
{
return ERROR_PROC_NOT_FOUND;
}
return( DDMAdminInterfaceConnect( DimIndexToHandle(hDimInterface),
(HANDLE)hEvent,
(BOOL)fBlocking,
(DWORD)dwCallersProcessId ) );
}
}
//**
//
// Call: RRouterInterfaceDisconnect
//
// Returns: ERROR_ACCESS_DENIED - The caller does not have sufficient priv.
// ERROR_DDM_NOT_RUNNING - This call cannot be made because DDM is
// not loaded
// non-zero returns from DDMAdminInterfaceDisconnect
//
// Description: Simply calles into DDM to do the work.
//
DWORD
RRouterInterfaceDisconnect(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hDimInterface
)
{
DWORD dwAccessStatus;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
{
return( ERROR_DDM_NOT_RUNNING );
}
else
{
DWORD
(*DDMAdminInterfaceDisconnect)( HANDLE ) =
(DWORD(*)( HANDLE ) )GetDDMEntryPoint("DDMAdminInterfaceDisconnect");
if(NULL == DDMAdminInterfaceDisconnect)
{
return ERROR_PROC_NOT_FOUND;
}
return( DDMAdminInterfaceDisconnect( DimIndexToHandle(hDimInterface) ) );
}
}
//**
//
// Call: RRouterInterfaceUpdatePhonebookInfo
//
// Returns: NO_ERROR - Success
/// ERROR_ACCESS_DENIED - The caller does not have sufficient priv.
// non-zero returns
//
// Description: Will update the phonebook information for a given interface
//
DWORD
RRouterInterfaceUpdatePhonebookInfo(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD hDimInterface
)
{
DWORD dwAccessStatus;
DWORD dwRetCode;
PROUTER_INTERFACE_OBJECT pIfObject = NULL;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR )
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN )
{
return( ERROR_DDM_NOT_RUNNING );
}
//
// Validate the interface handle and check to see if it is connected
//
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
DWORD (*IfObjectLoadPhonebookInfo)( ROUTER_INTERFACE_OBJECT * ) =
(DWORD(*)( ROUTER_INTERFACE_OBJECT * ))
GetDDMEntryPoint("IfObjectLoadPhonebookInfo");
if(NULL == IfObjectLoadPhonebookInfo)
{
dwRetCode = ERROR_PROC_NOT_FOUND;
break;
}
if ( ( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hDimInterface))) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// Load phonebook information for this interface
//
dwRetCode = IfObjectLoadPhonebookInfo( pIfObject );
} while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
return( dwRetCode );
}
DWORD
RRouterInterfaceSetCredentialsEx(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD hInterface
)
{
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
PWCHAR pszPath = NULL;
DWORD dwAccessStatus;
DWORD dwRetCode = NO_ERROR;
MPR_CREDENTIALSEX_0 * pCredsEx0 = NULL;
MPR_CREDENTIALSEX_1 * pCredsEx1 = NULL;
MPR_CREDENTIALSEXI * pCredsI = (MPR_CREDENTIALSEXI *)
pInfoStruct->pBuffer;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( (dwLevel != 0 ) &&
(dwLevel != 1 ) &&
(dwLevel != 2 ))
{
return( ERROR_NOT_SUPPORTED );
}
//
// Adjust the given buffer for any pointers to
// variable length data.
//
if ( dwLevel == 0 )
{
//
// Thunk the credentials structure
//
pCredsEx0 = LOCAL_ALLOC(LPTR,
pCredsI->dwSize + sizeof(MPR_CREDENTIALSEX_0));
if(pCredsEx0 == NULL)
{
return GetLastError();
}
pCredsEx0->dwSize = pCredsI->dwSize;
pCredsEx0->lpbCredentialsInfo = (PBYTE) (pCredsEx0 + 1);
CopyMemory(pCredsEx0->lpbCredentialsInfo,
((PBYTE) pCredsI) + pCredsI->dwOffset,
pCredsI->dwSize);
}
if( ( dwLevel == 1 )
|| ( dwLevel == 2 ))
{
//
// Thunk the credentials structure
//
pCredsEx1 = LOCAL_ALLOC(LPTR,
pCredsI->dwSize + sizeof(MPR_CREDENTIALSEX_1));
if(pCredsEx1 == NULL)
{
return GetLastError();
}
pCredsEx1->dwSize = pCredsI->dwSize;
pCredsEx1->lpbCredentialsInfo = (PBYTE) (pCredsEx1 + 1);
CopyMemory(pCredsEx1->lpbCredentialsInfo,
((PBYTE) pCredsI) + pCredsI->dwOffset,
pCredsI->dwSize);
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if (( 2 != dwLevel ) &&
( pIfObject = IfObjectGetPointer(DimIndexToHandle(hInterface))) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// Process Level 0
//
if ( dwLevel == 0 )
{
if (pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER)
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
dwRetCode = RpbkGetPhonebookPath( &pszPath );
if ( dwRetCode != NO_ERROR)
{
break;
}
dwRetCode = RasSetEapUserDataW(
NULL,
pszPath,
pIfObject->lpwsInterfaceName,
pCredsEx0->lpbCredentialsInfo,
pCredsEx0->dwSize);
}
//
// Process Levels 1 and 2
//
if (( dwLevel == 1 ) ||
( dwLevel == 2 ))
{
HANDLE hEntry = NULL;
if( ((NULL != pIfObject) &&
(pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER)) ||
(pCredsEx1->dwSize > (PWLEN+1) * sizeof(WCHAR)))
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
dwRetCode = RpbkGetPhonebookPath (&pszPath);
if( dwRetCode != NO_ERROR )
{
break;
}
{
RASCREDENTIALS rasCredentials;
ZeroMemory(&rasCredentials, sizeof(RASCREDENTIALS));
rasCredentials.dwSize = sizeof(RASCREDENTIALS);
if(dwLevel == 1)
{
rasCredentials.dwMask = RASCM_DDMPreSharedKey;
}
else if(dwLevel == 2)
{
rasCredentials.dwMask = RASCM_ServerPreSharedKey;
}
memcpy((PBYTE) &rasCredentials.szPassword,
pCredsEx1->lpbCredentialsInfo,
pCredsEx1->dwSize);
//
// Call Ras api to set the credentials.
//
dwRetCode = RasSetCredentials(
pszPath,
(NULL != pIfObject)
? pIfObject->lpwsInterfaceName
: NULL,
&rasCredentials,
(pCredsEx1->dwSize == 0)
? TRUE
: FALSE);
//
// If these are server credentials, the set might fail
// because of no listens being posted on l2tp ports.
// Attempt to post listens on l2tp ports now that we
// have a preshared key.
//
if( (ERROR_IPSEC_MM_AUTH_NOT_FOUND == dwRetCode)
&& (pCredsEx1->dwSize > 0)
&& (dwLevel == 2))
{
VOID (*DDMServicePostListens)(VOID *);
DDMServicePostListens = (VOID(*)(VOID *))
GetDDMEntryPoint("DDMServicePostListens");
if(DDMServicePostListens != NULL)
{
DWORD rdt = RDT_Tunnel_L2tp;
DDMServicePostListens((VOID *) &rdt);
dwRetCode = ERROR_SUCCESS;
}
}
}
}
} while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
// Cleanup
{
if ( pszPath )
{
RpbkFreePhonebookPath( pszPath );
}
if(pCredsEx0)
{
LOCAL_FREE(pCredsEx0);
}
if(pCredsEx1)
{
LOCAL_FREE(pCredsEx1);
}
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceSetCredEx returned %d", dwRetCode );
return( dwRetCode );
}
DWORD
RRouterInterfaceGetCredentialsEx(
IN MPR_SERVER_HANDLE hMprServer,
IN DWORD dwLevel,
IN PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD hInterface
)
{
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
PWCHAR pszPath = NULL;
DWORD dwAccessStatus;
DWORD dwRetCode = NO_ERROR, dwSize = 0;
MPR_CREDENTIALSEXI * pCredsI = NULL;
//
// Check if caller has access
//
if ( DimSecObjAccessCheck( DIMSVC_ALL_ACCESS, &dwAccessStatus) != NO_ERROR)
{
return( ERROR_ACCESS_DENIED );
}
if ( dwAccessStatus )
{
return( ERROR_ACCESS_DENIED );
}
if ( (dwLevel != 0 )
&& (dwLevel != 1 )
&& (dwLevel != 2 ))
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
do
{
if ( (dwLevel != 2)
&& (( pIfObject = IfObjectGetPointer(
DimIndexToHandle(hInterface))) == NULL ))
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
//
// Process Level 0
//
if ( dwLevel == 0 )
{
if (pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER)
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
dwRetCode = RpbkGetPhonebookPath( &pszPath );
if ( dwRetCode != NO_ERROR)
{
break;
}
// Find out how big the data is
//
dwSize = 0;
dwRetCode = RasGetEapUserDataW(
NULL,
pszPath,
pIfObject->lpwsInterfaceName,
NULL,
&dwSize);
if ( (dwRetCode != NO_ERROR) &&
(dwRetCode != ERROR_BUFFER_TOO_SMALL)
)
{
break;
}
// Allocate the return value
//
pCredsI = (MPR_CREDENTIALSEXI *)
MIDL_user_allocate(dwSize + sizeof(MPR_CREDENTIALSEXI));
if ( pCredsI == NULL )
{
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Initialize
ZeroMemory(pCredsI, dwSize + sizeof(MPR_CREDENTIALSEXI));
pCredsI->dwSize = dwSize;
pCredsI->dwOffset = FIELD_OFFSET(MPR_CREDENTIALSEXI, bData);
if ( pCredsI->dwSize == 0)
{
dwRetCode = NO_ERROR;
break;
}
// Read in the credentials info
//
// pCredsEx0->lpbCredentialsInfo = (BYTE*) (pCredsEx0 + 1);
dwRetCode = RasGetEapUserDataW(
NULL,
pszPath,
pIfObject->lpwsInterfaceName,
pCredsI->bData,
&dwSize);
if ( dwRetCode != NO_ERROR )
{
break;
}
}
else if( (dwLevel == 1 ) || (dwLevel == 2))
{
RASCREDENTIALS rasCredentials;
if ( (dwLevel != 2)
&& (pIfObject->IfType != ROUTER_IF_TYPE_FULL_ROUTER))
{
dwRetCode = ERROR_INVALID_PARAMETER;
break;
}
dwRetCode = RpbkGetPhonebookPath( &pszPath );
if ( dwRetCode != NO_ERROR)
{
break;
}
ZeroMemory(&rasCredentials, sizeof(RASCREDENTIALS));
rasCredentials.dwSize = sizeof(RASCREDENTIALS);
if(dwLevel == 1)
{
rasCredentials.dwMask = RASCM_DDMPreSharedKey;
}
else if(dwLevel == 2)
{
rasCredentials.dwMask = RASCM_ServerPreSharedKey;
}
dwRetCode = RasGetCredentials(
pszPath,
(NULL != pIfObject)
? pIfObject->lpwsInterfaceName
: NULL,
&rasCredentials);
if(dwRetCode != NO_ERROR)
{
break;
}
dwSize = (1 + wcslen(rasCredentials.szPassword)) * sizeof(WCHAR);
//
// allocate for pCredsEx1
//
pCredsI = (MPR_CREDENTIALSEXI *)
MIDL_user_allocate(dwSize + sizeof(MPR_CREDENTIALSEXI));
if(NULL == pCredsI)
{
break;
}
ZeroMemory(pCredsI, dwSize + sizeof(MPR_CREDENTIALSEXI));
pCredsI->dwSize = dwSize;
pCredsI->dwOffset = FIELD_OFFSET(MPR_CREDENTIALSEXI, bData);
CopyMemory((pCredsI->bData),
(PBYTE) rasCredentials.szPassword,
dwSize);
}
} while( FALSE );
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
// Assign the return value
//
if ( dwRetCode == NO_ERROR )
{
pInfoStruct->pBuffer = (BYTE*)pCredsI;
pInfoStruct->dwBufferSize =
sizeof(MPR_CREDENTIALSEXI) + pCredsI->dwSize;
}
// Cleanup
{
if ( pszPath )
{
RpbkFreePhonebookPath( pszPath );
}
}
TracePrintfExA( gblDIMConfigInfo.dwTraceId, DIM_TRACE_FLAGS,
"InterfaceSetCredEx returned %d", dwRetCode );
return( dwRetCode );
}