1289 lines
34 KiB
C
1289 lines
34 KiB
C
|
/********************************************************************/
|
|||
|
/** 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 );
|
|||
|
}
|