/********************************************************************/ /** 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 #include // Generated by MIDL #include "rpbk.h" #include #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 ); }