|
|
/********************************************************************/ /** Copyright(c) 1995 Microsoft Corporation. **/ /********************************************************************/
//***
//
// Filename: main.c
//
// Description: This module contains the main procedure of the Dynamic
// Interface Manager server service. It will contain code to
// initialize and install itself. It also contains
// code to respond to the server controller. It will also
// handle service shutdown.
//
// History: May 11,1995. NarenG Created original version.
//
#define _ALLOCATE_DIM_GLOBALS_
#include "dimsvcp.h"
#include <winsvc.h>
#include <winuser.h>
#include <dbt.h>
#include <ndisguid.h>
#include <wmium.h>
#include <rpc.h>
#include <iaspolcy.h>
#include <iasext.h>
#include <lmserver.h>
#include <srvann.h>
#include <ddmif.h>
#define RAS_CONTROL_CONFIGURE 128
//**
//
// Call: MediaSenseCallback
//
// Returns: None
//
// Description:
//
VOID WINAPI MediaSenseCallback( PWNODE_HEADER pWnodeHeader, UINT_PTR NotificationContext ) { ROUTER_INTERFACE_OBJECT * pIfObject; PWNODE_SINGLE_INSTANCE pWnode = (PWNODE_SINGLE_INSTANCE)pWnodeHeader; LPWSTR lpwsName = (LPWSTR)RtlOffsetToPointer( pWnode, pWnode->OffsetInstanceName );
if ( (gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING) || (gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOPPED )) { return; }
//
// Get the information for the media disconnect.
//
if ( memcmp( &(pWnodeHeader->Guid), &GUID_NDIS_STATUS_MEDIA_DISCONNECT, sizeof( GUID ) ) == 0 ) { DIMTRACE1("MediaSenseCallback for sense disconnect called for %ws", lpwsName );
IfObjectNotifyOfMediaSenseChange(); } else { //
// Get the information for the media connect.
//
if ( memcmp( &(pWnodeHeader->Guid), &GUID_NDIS_STATUS_MEDIA_CONNECT, sizeof( GUID ) ) == 0 ) { DIMTRACE1("MediaSenseCallback for sense connect called for %ws", lpwsName );
IfObjectNotifyOfMediaSenseChange(); } } }
//**
//
// Call: MediaSenseRegister
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description:
//
DWORD MediaSenseRegister( IN BOOL fRegister ) { DWORD dwRetCode = NO_ERROR; PVOID pvDeliveryInfo = MediaSenseCallback;
dwRetCode = WmiNotificationRegistration( (LPGUID)(&GUID_NDIS_STATUS_MEDIA_CONNECT), (BOOLEAN)fRegister, pvDeliveryInfo, (ULONG_PTR)NULL, NOTIFICATION_CALLBACK_DIRECT );
if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); }
dwRetCode = WmiNotificationRegistration( (LPGUID)(&GUID_NDIS_STATUS_MEDIA_DISCONNECT), (BOOLEAN)fRegister, pvDeliveryInfo, (ULONG_PTR)NULL, NOTIFICATION_CALLBACK_DIRECT );
if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); }
return( NO_ERROR ); }
//**
//
// Call: BindingsNotificationsCallback
//
// Returns: None
//
// Description:
//
VOID WINAPI BindingsNotificationsCallback( PWNODE_HEADER pWnodeHeader, UINT_PTR NotificationContext ) { LPWSTR lpwszGUIDStart; LPWSTR lpwszGUIDEnd; LPWSTR lpwszGUID; WCHAR wchGUIDSaveLast; ROUTER_INTERFACE_OBJECT * pIfObject; PWNODE_SINGLE_INSTANCE pWnode = (PWNODE_SINGLE_INSTANCE)pWnodeHeader; LPWSTR lpwsName = (LPWSTR)RtlOffsetToPointer( pWnode, pWnode->OffsetInstanceName ); LPWSTR lpwsTransportName = (LPWSTR)RtlOffsetToPointer( pWnode, pWnode->DataBlockOffset );
if ( (gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING) || (gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOPPED )) { return; }
//
// Extract GUID from the \device\GUID name
//
lpwszGUID = lpwsTransportName + wcslen( lpwsTransportName ) + 1; lpwszGUIDStart = wcsrchr( lpwszGUID, L'{' ); lpwszGUIDEnd = wcsrchr( lpwszGUID, L'}' );
if ( (lpwszGUIDStart != NULL ) && (lpwszGUIDEnd != NULL )) { wchGUIDSaveLast = *(lpwszGUIDEnd+1);
EnterCriticalSection( &(gblInterfaceTable.CriticalSection));
*(lpwszGUIDEnd+1) = (WCHAR)NULL;
pIfObject = IfObjectGetPointerByName( lpwszGUIDStart, FALSE );
*(lpwszGUIDEnd+1) = wchGUIDSaveLast;
//
// If we got a bind notification
//
if ( memcmp( &(pWnodeHeader->Guid), &GUID_NDIS_NOTIFY_BIND, sizeof( GUID ) ) == 0) { DIMTRACE2("BindingsNotificationsCallback BIND for %ws,Transport=%ws", lpwsName, lpwsTransportName ); //
// If we have this interface loaded.
//
if ( pIfObject != NULL ) { //
// If this interface is being bound to IP
//
if ( _wcsicmp( L"TCPIP", lpwsTransportName ) == 0 ) { DWORD dwTransportIndex = GetTransportIndex( PID_IP );
//
// If IP routermanager is loaded and this interface is not
// already registered with it
//
if (( dwTransportIndex != -1 ) && ( pIfObject->Transport[dwTransportIndex].hInterface == INVALID_HANDLE_VALUE )) { AddInterfacesToRouterManager( lpwszGUIDStart, PID_IP ); } }
//
// If this interface is being bound to IPX
//
if ( _wcsicmp( L"NWLNKIPX", lpwsTransportName ) == 0 ) { DWORD dwTransportIndex = GetTransportIndex( PID_IPX );
//
// If IPX routermanager is loaded and this interface is not
// already registered with it
//
if (( dwTransportIndex != -1 ) && ( pIfObject->Transport[dwTransportIndex].hInterface == INVALID_HANDLE_VALUE )) { AddInterfacesToRouterManager( lpwszGUIDStart, PID_IPX ); } } } } else if (memcmp( &(pWnodeHeader->Guid),&GUID_NDIS_NOTIFY_UNBIND,sizeof(GUID))==0) { if ( pIfObject != NULL ) { //
// Get the information for the media connect.
//
DIMTRACE2("BindingsNotificationsCallback UNDBIND for %ws,Transport=%ws", lpwsName, lpwsTransportName );
if ( _wcsicmp( L"TCPIP", lpwsTransportName ) == 0 ) { IfObjectDeleteInterfaceFromTransport( pIfObject, PID_IP ); }
if ( _wcsicmp( L"NWLNKIPX", lpwsTransportName ) == 0 ) { IfObjectDeleteInterfaceFromTransport( pIfObject, PID_IPX ); } } }
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) ); } }
//**
//
// Call: BindingsNotificationsRegister
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description:
//
DWORD BindingsNotificationsRegister( IN BOOL fRegister ) { DWORD dwRetCode = NO_ERROR; PVOID pvDeliveryInfo = BindingsNotificationsCallback;
dwRetCode = WmiNotificationRegistration( (LPGUID)(&GUID_NDIS_NOTIFY_BIND), (BOOLEAN)fRegister, pvDeliveryInfo, (ULONG_PTR)NULL, NOTIFICATION_CALLBACK_DIRECT );
if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); }
dwRetCode = WmiNotificationRegistration( (LPGUID)(&GUID_NDIS_NOTIFY_UNBIND), (BOOLEAN)fRegister, pvDeliveryInfo, (ULONG_PTR)NULL, NOTIFICATION_CALLBACK_DIRECT );
if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); }
return( NO_ERROR ); }
//**
//
// Call: DimAnnounceServiceStatus
//
// Returns: none
//
// Description: Will simly call SetServiceStatus to inform the service
// control manager of this service's current status.
//
VOID DimAnnounceServiceStatus( VOID ) { BOOL dwRetCode;
ASSERT (gblDIMConfigInfo.hServiceStatus);
//
// Increment the checkpoint in a pending state:
//
switch( gblDIMConfigInfo.ServiceStatus.dwCurrentState ) { case SERVICE_START_PENDING: case SERVICE_STOP_PENDING:
gblDIMConfigInfo.ServiceStatus.dwCheckPoint++;
break;
default: break; }
dwRetCode = SetServiceStatus( gblDIMConfigInfo.hServiceStatus, &gblDIMConfigInfo.ServiceStatus );
if ( dwRetCode == FALSE ) { //TracePrintfExA( gblDIMConfigInfo.dwTraceId,
// TRACE_DIM,
// "SetServiceStatus returned %d", GetLastError() );
} }
//**
//
// Call: DimCleanUp
//
// Returns: none
//
// Description: Will free any allocated memory, deinitialize RPC, deinitialize
// the kernel-mode server and unload it if it was loaded.
// This could have been called due to an error on SERVICE_START
// or normal termination.
//
VOID DimCleanUp( IN DWORD dwError ) { DWORD dwIndex; //
// Announce that we are stopping
//
gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = 0; gblDIMConfigInfo.ServiceStatus.dwCheckPoint = 1; gblDIMConfigInfo.ServiceStatus.dwWaitHint = 200000;
DimAnnounceServiceStatus();
if ( gbldwDIMComponentsLoaded & DIM_RPC_LOADED ) { DimTerminateRPC(); }
//
// Stop the timer and delete the timer Q if there is one.
//
if ( gblDIMConfigInfo.hTimerQ != NULL ) { RtlDeleteTimerQueueEx( gblDIMConfigInfo.hTimerQ, INVALID_HANDLE_VALUE ); }
EnterCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
DeleteCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
if ( gbldwDIMComponentsLoaded & DIM_DDM_LOADED ) { //
// If we are not in LANOnly mode then stop DDM
//
if ( gblDIMConfigInfo.dwRouterRole != ROUTER_ROLE_LAN ) { if ( gblhEventDDMServiceState != NULL ) { SetEvent( gblhEventDDMServiceState ); } }
//
// Wait for all threads in use to stop
//
while( gblDIMConfigInfo.dwNumThreadsRunning > 0 ) { Sleep( 1000 ); } }
DimAnnounceServiceStatus();
//
// Tear down and free everything
//
if ( gbldwDIMComponentsLoaded & DIM_RMS_LOADED ) { DimUnloadRouterManagers(); }
//
// Unregister for media sense
//
MediaSenseRegister( FALSE );
//
// Unregister for bind/unbind sense
//
BindingsNotificationsRegister( FALSE );
//
// Need to sleep to give the router managers a change to unload
// bug# 78711
//
Sleep( 2000 );
if ( gblhModuleDDM != NULL ) { FreeLibrary( gblhModuleDDM ); }
//
// If security object was created
//
if ( gbldwDIMComponentsLoaded & DIM_SECOBJ_LOADED ) { DimSecObjDelete(); }
if ( gblDIMConfigInfo.hMprConfig != NULL ) { MprConfigServerDisconnect( gblDIMConfigInfo.hMprConfig ); }
if ( gblhEventDDMTerminated != NULL ) { CloseHandle( gblhEventDDMTerminated ); }
if ( gblhEventDDMServiceState != NULL ) { CloseHandle( gblhEventDDMServiceState ); }
if ( gblhEventTerminateDIM != NULL ) { CloseHandle( gblhEventTerminateDIM ); }
if ( gblhEventRMState != NULL ) { CloseHandle( gblhEventRMState ); }
if ( gblDIMConfigInfo.hObjectRouterIdentity != NULL ) { RouterIdentityObjectClose( gblDIMConfigInfo.hObjectRouterIdentity ); }
//
// Wait for everybody to release this and then delete it
//
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
DeleteCriticalSection( &(gblInterfaceTable.CriticalSection) );
gbldwDIMComponentsLoaded = 0;
if ( gblDIMConfigInfo.dwTraceId != INVALID_TRACEID ) { TraceDeregisterA( gblDIMConfigInfo.dwTraceId ); }
RouterLogDeregister( gblDIMConfigInfo.hLogEvents );
//
// Destroy private heap
//
if ( gblDIMConfigInfo.hHeap != NULL ) { HeapDestroy( gblDIMConfigInfo.hHeap ); }
DIMTRACE1("DimCleanup completed for error %d", dwError ); //
// Zero init all the globals
//
gblRouterManagers = NULL; gbldwDIMComponentsLoaded = 0; gblhEventDDMTerminated = NULL; gblhEventRMState = NULL; gblhEventDDMServiceState = NULL; gblhModuleDDM = NULL; gblhEventTerminateDIM = NULL; ZeroMemory( &gblInterfaceTable, sizeof( gblInterfaceTable ) );
{ SERVICE_STATUS_HANDLE svchandle = gblDIMConfigInfo.hServiceStatus; ZeroMemory( &gblDIMConfigInfo, sizeof( gblDIMConfigInfo ) ); gblDIMConfigInfo.hServiceStatus = svchandle; } //
// Zero out only the procedure entrypoints. This is a side effect of
// the merge into svchost.exe since svchost doesn't unload mprdim
// anymore when router stops.
//
for ( dwIndex = 0; gblDDMFunctionTable[dwIndex].lpEntryPointName != NULL; dwIndex ++ ) { gblDDMFunctionTable[dwIndex].pEntryPoint = NULL; }
if ( dwError == NO_ERROR ) { gblDIMConfigInfo.ServiceStatus.dwWin32ExitCode = NO_ERROR; } else { gblDIMConfigInfo.ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; }
gblDIMConfigInfo.ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS; gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_STOPPED; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = 0; gblDIMConfigInfo.ServiceStatus.dwCheckPoint = 0; gblDIMConfigInfo.ServiceStatus.dwWaitHint = 0; gblDIMConfigInfo.ServiceStatus.dwServiceSpecificExitCode = dwError;
DimAnnounceServiceStatus(); }
//**
//
// Call: ServiceHandlerEx
//
// Returns: none
//
// Description: Will respond to control requests from the service controller.
//
DWORD ServiceHandlerEx( IN DWORD dwControlCode, IN DWORD dwEventType, IN LPVOID lpEventData, IN LPVOID lpContext ) { DWORD dwRetCode = NO_ERROR;
switch( dwControlCode ) { case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN:
if ( ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING) || ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOPPED )) { break; }
DIMTRACE("Service control stop or shutdown called");
//
// Announce that we are stopping
//
gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = 0; gblDIMConfigInfo.ServiceStatus.dwCheckPoint = 1; gblDIMConfigInfo.ServiceStatus.dwWaitHint = 200000;
DimAnnounceServiceStatus();
//
// Make sure serice is started before initiating a stop
//
while( !( gbldwDIMComponentsLoaded & DIM_SERVICE_STARTED ) ) { Sleep( 1000 ); }
SetEvent( gblhEventTerminateDIM );
return( NO_ERROR );
case SERVICE_CONTROL_PAUSE:
if ( ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING) || ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_PAUSED )) break;
gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_PAUSED; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = 0; gblDIMConfigInfo.ServiceStatus.dwCheckPoint = 0; gblDIMConfigInfo.ServiceStatus.dwWaitHint = 200000; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
SetEvent( gblhEventDDMServiceState );
break;
case SERVICE_CONTROL_CONTINUE:
if ( ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING ) || ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_RUNNING ) ) break;
gblDIMConfigInfo.ServiceStatus.dwCheckPoint = 0; gblDIMConfigInfo.ServiceStatus.dwWaitHint = 0; gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_RUNNING; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
SetEvent( gblhEventDDMServiceState );
break;
case SERVICE_CONTROL_DEVICEEVENT:
if ( ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING) || ( gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_STOPPED )) { break; }
if ( lpEventData != NULL) { DEV_BROADCAST_DEVICEINTERFACE* pInfo = (DEV_BROADCAST_DEVICEINTERFACE*)lpEventData;
if ( pInfo->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE ) { ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
if ( ( dwEventType == DBT_DEVICEARRIVAL ) || ( dwEventType == DBT_DEVICEREMOVECOMPLETE ) ) { //
// Extract GUID from the \device\GUID name
//
LPWSTR lpwszGUIDStart = wcsrchr( pInfo->dbcc_name, L'{' ); LPWSTR lpwszGUIDEnd = wcsrchr( pInfo->dbcc_name, L'}' );
if ( lpwszGUIDStart != NULL ) { WCHAR wchGUIDSaveLast = *(lpwszGUIDEnd+1);
EnterCriticalSection( &(gblInterfaceTable.CriticalSection));
*(lpwszGUIDEnd+1) = (WCHAR)NULL;
pIfObject = IfObjectGetPointerByName( lpwszGUIDStart, FALSE );
*(lpwszGUIDEnd+1) = wchGUIDSaveLast;
if ( dwEventType == DBT_DEVICEARRIVAL ) { if ( pIfObject == NULL ) { DIMTRACE1("Device arrival:[%ws]", lpwszGUIDStart );
RegLoadInterfaces( lpwszGUIDStart, TRUE ); } } else { if ( pIfObject != NULL ) { DIMTRACE1("Device removed:[%ws]", lpwszGUIDStart );
IfObjectDeleteInterfaceFromTransport( pIfObject, PID_IP );
IfObjectDeleteInterfaceFromTransport( pIfObject, PID_IPX);
IfObjectRemove( pIfObject->hDIMInterface ); } }
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) ); } } } }
break;
case RAS_CONTROL_CONFIGURE:
//
// Code for dynamic configuration of RAP
//
DIMTRACE( "Received Remote Access Policy change control message" );
{ //
// thread needs to be COM initialized
//
HRESULT hResult = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if ( SUCCEEDED( hResult ) ) { //
// configure, doesn't matter if the API call fails
//
ConfigureIas(); CoUninitialize(); } }
break;
case SERVICE_CONTROL_POWEREVENT:
switch( dwEventType ) { case PBT_APMQUERYSTANDBY: case PBT_APMQUERYSUSPEND:
//
// Fail only if we are in LAN only mode, otherwise defer
// decision to RASMAN/NDISWAN
//
if ( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN ) { dwRetCode = ERROR_ACTIVE_CONNECTIONS; }
break;
case PBT_APMRESUMECRITICAL: default: { break; } }
break;
case SERVICE_CONTROL_NETBINDADD: case SERVICE_CONTROL_NETBINDREMOVE: case SERVICE_CONTROL_NETBINDENABLE: case SERVICE_CONTROL_NETBINDDISABLE:
break;
default:
return( ERROR_CALL_NOT_IMPLEMENTED );
break; }
DimAnnounceServiceStatus();
return( dwRetCode ); }
//**
//
// Call: ServiceMain
//
// Returns: None
//
// Description: This is the main procedure for the DIM Server Service. It
// will be called when the service is supposed to start itself.
// It will do all service wide initialization.
//
VOID ServiceMain( IN DWORD argc, // Command line arguments. Will be ignored.
IN LPWSTR * lpwsServiceArgs ) { DIM_INFO DimInfo; DWORD dwRetCode; DWORD dwIndex; DWORD (*DDMServiceInitialize)( DIM_INFO * ); VOID (*DDMServicePostListens)( VOID *);
UNREFERENCED_PARAMETER( argc ); UNREFERENCED_PARAMETER( lpwsServiceArgs );
gblDIMConfigInfo.hServiceStatus = RegisterServiceCtrlHandlerEx( TEXT("remoteaccess"), ServiceHandlerEx, NULL );
if ( !gblDIMConfigInfo.hServiceStatus ) { return; }
gblDIMConfigInfo.ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS; gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
DimAnnounceServiceStatus();
gblDIMConfigInfo.dwTraceId = TraceRegisterA( "Router" );
try { //
// Mutex around the interface table
//
InitializeCriticalSection( &(gblInterfaceTable.CriticalSection) );
//
// Mutex around setting router identity attributes
//
InitializeCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) ); } except (EXCEPTION_EXECUTE_HANDLER) { return; }
gblDIMConfigInfo.hLogEvents = RouterLogRegister( DIM_SERVICE_NAME );
/*
if ( gblDIMConfigInfo.hLogEvents == NULL ) { DimCleanUp( GetLastError() ); return; } */
//
// Create DIM private heap
//
gblDIMConfigInfo.hHeap = HeapCreate( 0, DIM_HEAP_INITIAL_SIZE, DIM_HEAP_MAX_SIZE );
if ( gblDIMConfigInfo.hHeap == NULL ) { DimCleanUp( GetLastError() ); return; }
//
// Lead DIM parameters from the registry
//
if ( ( dwRetCode = RegLoadDimParameters() ) != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
DimAnnounceServiceStatus();
//
// Create event that will be used by DIM to make sure all the Router
// Managers have shut down when DIM is stopping.
//
gblhEventRMState = CreateEvent( NULL, FALSE, FALSE, NULL );
if ( gblhEventRMState == (HANDLE)NULL ) { DimCleanUp( GetLastError() ); return; }
//
// Announce that we have successfully started.
//
gblDIMConfigInfo.ServiceStatus.dwCurrentState = SERVICE_RUNNING; gblDIMConfigInfo.ServiceStatus.dwCheckPoint = 0; gblDIMConfigInfo.ServiceStatus.dwWaitHint = 0; gblDIMConfigInfo.ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
DimAnnounceServiceStatus();
//
// Load the router managers
//
gbldwDIMComponentsLoaded |= DIM_RMS_LOADED;
if ( ( dwRetCode = RegLoadRouterManagers() ) != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
//
// Create event that will be used to shutdown the DIM service
//
gblhEventTerminateDIM = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( gblhEventTerminateDIM == (HANDLE)NULL ) { DimCleanUp( GetLastError() ); return; }
//
// If not in LAN only mode load the Demand Dial Manager DLL
//
if ( gblDIMConfigInfo.dwRouterRole != ROUTER_ROLE_LAN ) { //
// Create event that will be used by DDM to notify DIM that it has
// terminated
//
gblhEventDDMTerminated = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( gblhEventDDMTerminated == (HANDLE)NULL ) { DimCleanUp( GetLastError() ); return; }
//
// Create event that will be used by DIM to notify DDM that there is
// is a change is state of this service
//
gblhEventDDMServiceState = CreateEvent( NULL, FALSE, FALSE, NULL );
if ( gblhEventDDMServiceState == (HANDLE)NULL ) { DimCleanUp( GetLastError() ); return; }
if ( ( dwRetCode = RegLoadDDM() ) != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
//
// Initialize the DDM
//
DDMServiceInitialize = (DWORD(*)( DIM_INFO * )) GetDDMEntryPoint( "DDMServiceInitialize" );
if ( DDMServiceInitialize == NULL ) { DimCleanUp( ERROR_PROC_NOT_FOUND ); return; }
DDMServicePostListens = (VOID(*)( VOID *)) GetDDMEntryPoint( "DDMServicePostListens" );
if ( DDMServicePostListens == NULL ) { DimCleanUp( ERROR_PROC_NOT_FOUND ); return; }
DimInfo.pInterfaceTable = &gblInterfaceTable; DimInfo.pRouterManagers = gblRouterManagers; DimInfo.dwNumRouterManagers = gblDIMConfigInfo.dwNumRouterManagers; DimInfo.pServiceStatus = &gblDIMConfigInfo.ServiceStatus; DimInfo.phEventDDMServiceState = &gblhEventDDMServiceState; DimInfo.phEventDDMTerminated = &gblhEventDDMTerminated; DimInfo.dwTraceId = gblDIMConfigInfo.dwTraceId; DimInfo.hLogEvents = gblDIMConfigInfo.hLogEvents; DimInfo.lpdwNumThreadsRunning = &(gblDIMConfigInfo.dwNumThreadsRunning); DimInfo.lpfnIfObjectAllocateAndInit = IfObjectAllocateAndInit; DimInfo.lpfnIfObjectGetPointerByName = IfObjectGetPointerByName; DimInfo.lpfnIfObjectGetPointer = IfObjectGetPointer; DimInfo.lpfnIfObjectRemove = IfObjectRemove; DimInfo.lpfnIfObjectInsertInTable = IfObjectInsertInTable; DimInfo.lpfnIfObjectWANDeviceInstalled = IfObjectWANDeviceInstalled; DimInfo.lpfnRouterIdentityObjectUpdate = RouterIdentityObjectUpdateDDMAttributes;
if ( ( dwRetCode = DDMServiceInitialize( &DimInfo ) ) != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
gbldwDIMComponentsLoaded |= DIM_DDM_LOADED;
//
// Initialize random number generator that is used by DDM
//
srand( GetTickCount() ); }
//
// What is the platform
//
RtlGetNtProductType( &(gblDIMConfigInfo.NtProductType) );
//
// Need this to do GUID to friendly name mapping
//
MprConfigServerConnect( NULL, &gblDIMConfigInfo.hMprConfig );
//
// Add the various interfaces
//
dwRetCode = RegLoadInterfaces( NULL, gblDIMConfigInfo.dwNumRouterManagers );
if ( dwRetCode != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
if ( ( dwRetCode = DimSecObjCreate() ) != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
gbldwDIMComponentsLoaded |= DIM_SECOBJ_LOADED;
dwRetCode = DimInitializeRPC( gblDIMConfigInfo.dwRouterRole == ROUTER_ROLE_LAN );
if ( dwRetCode != NO_ERROR ) { DimCleanUp( dwRetCode ); return; }
gbldwDIMComponentsLoaded |= DIM_RPC_LOADED;
//
// Start a timer that when fired will go out and plumb the router attributes
//
if ( RtlCreateTimerQueue( &(gblDIMConfigInfo.hTimerQ) ) == STATUS_SUCCESS ) { //
// We wait 5 minutes in the case where we are the router providing
// connectivity to the DC so we wait for all routing protocols to
// stabalize and propagate.
//
gblDIMConfigInfo.dwRouterIdentityDueTime = 5*60*1000;
RtlCreateTimer( gblDIMConfigInfo.hTimerQ, &(gblDIMConfigInfo.hTimer), RouterIdentityObjectUpdateAttributes, (PVOID)TRUE, gblDIMConfigInfo.dwRouterIdentityDueTime, 0, WT_EXECUTEDEFAULT ); }
GetSystemTimeAsFileTime( (FILETIME*)&gblDIMConfigInfo.qwStartTime );
if ( gbldwDIMComponentsLoaded & DIM_DDM_LOADED ) { DDMServicePostListens(NULL); }
//
// Set the RAS bit for NetServerEnum
//
if( I_ScSetServiceBits( gblDIMConfigInfo.hServiceStatus, SV_TYPE_DIALIN_SERVER, TRUE, TRUE, NULL) == FALSE ) { DimCleanUp( GetLastError() );
return; }
//
// Register for device notifications. Specifically, we're interested
// in network adapters coming and going. If this fails, we proceed
// anyway.
//
{ DEV_BROADCAST_DEVICEINTERFACE PnpFilter;
ZeroMemory( &PnpFilter, sizeof( PnpFilter ) ); PnpFilter.dbcc_size = sizeof( PnpFilter ); PnpFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; PnpFilter.dbcc_classguid = GUID_NDIS_LAN_CLASS;
gblDIMConfigInfo.hDeviceNotification = RegisterDeviceNotification( (HANDLE)gblDIMConfigInfo.hServiceStatus, &PnpFilter, DEVICE_NOTIFY_SERVICE_HANDLE );
if ( gblDIMConfigInfo.hDeviceNotification == NULL ) { dwRetCode = GetLastError();
DIMTRACE1( "RegisterDeviceNotification failed with error %d", dwRetCode );
DimCleanUp( dwRetCode );
return; } }
//
// Register for media sense events
//
if ( ( dwRetCode = MediaSenseRegister( TRUE ) ) != NO_ERROR ) { DIMTRACE1( "Registering for media sense failed with dwRetCode = %d", dwRetCode );
dwRetCode = NO_ERROR; }
//
// Register for BIND/UNBIND notifications
//
if ( ( dwRetCode = BindingsNotificationsRegister( TRUE ) ) != NO_ERROR ) { DIMTRACE1( "Registering for bindings notifications failed with dwRetCode = %d", dwRetCode );
dwRetCode = NO_ERROR; }
DIMTRACE( "Multi-Protocol Router started successfully" );
gbldwDIMComponentsLoaded |= DIM_SERVICE_STARTED;
//
// Notify all router managers that all interfaces have been loaded at
// service start.
//
for (dwIndex = 0; dwIndex < gblDIMConfigInfo.dwNumRouterManagers; dwIndex++) { gblRouterManagers[dwIndex].DdmRouterIf.RouterBootComplete(); }
//
// If we are a demand dial router
//
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_WAN ) { DWORD dwXportIndex = GetTransportIndex( PID_IP );
//
// Initate persistent demand dial conenctions
//
DWORD (*IfObjectInitiatePersistentConnections)() = (DWORD(*)())GetDDMEntryPoint("IfObjectInitiatePersistentConnections");
IfObjectInitiatePersistentConnections();
//
// If a WAN device is installed and IP is installed then we
// start advertizing on specific multicast address so as to make this
// router discoverable
//
IfObjectWANDeviceInstalled( DimInfo.fWANDeviceInstalled ); }
//
// Just wait here for DIM to terminate.
//
dwRetCode = WaitForSingleObject( gblhEventTerminateDIM, INFINITE );
if ( dwRetCode == WAIT_FAILED ) { dwRetCode = GetLastError(); } else { dwRetCode = NO_ERROR; }
DimCleanUp( dwRetCode ); }
|