You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3535 lines
98 KiB
3535 lines
98 KiB
/********************************************************************/
|
|
/** 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 (WINVER >= 0x0501)
|
|
if ( dwTransportId == PID_IP )
|
|
#else
|
|
if ( ( dwTransportId == PID_IP ) || ( dwTransportId == PID_IPX ) )
|
|
#endif
|
|
{
|
|
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( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
|
|
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( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
|
|
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( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
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( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
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_1 * pMprIf1;
|
|
MPRI_INTERFACE_2 * pMprIf2;
|
|
|
|
//
|
|
// 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 > 2 )
|
|
{
|
|
return( ERROR_NOT_SUPPORTED );
|
|
}
|
|
|
|
if ( ( pInfoStruct == NULL ) || ( pInfoStruct->dwBufferSize == 0 ) ||
|
|
( pInfoStruct->pBuffer == NULL ) )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
pMprIf0 = (MPRI_INTERFACE_0*) pInfoStruct->pBuffer;
|
|
|
|
pMprIf1 = (MPRI_INTERFACE_1*) pInfoStruct->pBuffer;
|
|
|
|
pMprIf2 = (MPRI_INTERFACE_2*) pInfoStruct->pBuffer;
|
|
|
|
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( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
}
|
|
}
|
|
|
|
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,
|
|
NULL);
|
|
|
|
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) );
|
|
|
|
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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
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) );
|
|
|
|
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 *, VOID * ) =
|
|
(DWORD(*)( ROUTER_INTERFACE_OBJECT *, VOID * ))
|
|
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, NULL );
|
|
|
|
} 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 = 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 );
|
|
}
|
|
|
|
if ( ( pInfoStruct == NULL ) || ( pInfoStruct->dwBufferSize == 0 ) ||
|
|
( pInfoStruct->pBuffer == NULL ) )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
pCredsI = (MPR_CREDENTIALSEXI *) pInfoStruct->pBuffer;
|
|
|
|
//
|
|
// 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 ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
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 ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
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)
|
|
{
|
|
SecureZeroMemory(pCredsEx0, sizeof(*pCredsEx0));
|
|
LOCAL_FREE(pCredsEx0);
|
|
}
|
|
|
|
if(pCredsEx1)
|
|
{
|
|
SecureZeroMemory(pCredsEx1, sizeof(*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)
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
ZeroMemory(pCredsI, dwSize + sizeof(MPR_CREDENTIALSEXI));
|
|
pCredsI->dwSize = dwSize;
|
|
pCredsI->dwOffset = FIELD_OFFSET(MPR_CREDENTIALSEXI, bData);
|
|
|
|
CopyMemory((pCredsI->bData),
|
|
(PBYTE) rasCredentials.szPassword,
|
|
dwSize);
|
|
|
|
SecureZeroMemory(&rasCredentials, sizeof(RASCREDENTIALS));
|
|
}
|
|
|
|
} 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 );
|
|
}
|
|
|
|
|