335 lines
9.1 KiB
C
335 lines
9.1 KiB
C
/********************************************************************/
|
||
/* Copyright(c) 1995 Microsoft Corporation */
|
||
/********************************************************************/
|
||
|
||
//***
|
||
//
|
||
// Filename: evdsptch.c
|
||
//
|
||
// Description: This module contains the event dispatcher for the
|
||
// DDM's procedure-driven state machine
|
||
//
|
||
// Author: Stefan Solomon (stefans) June 9, 1992.
|
||
//
|
||
//***
|
||
#include "ddm.h"
|
||
#include "handlers.h"
|
||
#include "objects.h"
|
||
#include "timer.h"
|
||
#include "util.h"
|
||
#include <raserror.h>
|
||
#include <ddmif.h>
|
||
#include <sechost.h>
|
||
#include <stdlib.h>
|
||
#include "rasmanif.h"
|
||
|
||
//***
|
||
//
|
||
// Function: EventDispatcher
|
||
//
|
||
// Descr: Waits for events to be signaled and invokes the proper
|
||
// event handler. Returns when DDM has terminated.
|
||
//
|
||
//***
|
||
DWORD
|
||
EventDispatcher(
|
||
IN LPVOID arg
|
||
)
|
||
{
|
||
EVENT_HANDLER * pEventHandler;
|
||
DWORD dwSignaledEvent;
|
||
|
||
//
|
||
// Indicate that this thread is running
|
||
//
|
||
|
||
InterlockedIncrement( gblDDMConfigInfo.lpdwNumThreadsRunning );
|
||
|
||
RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyParameters,
|
||
TRUE,
|
||
REG_NOTIFY_CHANGE_LAST_SET,
|
||
gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION],
|
||
TRUE );
|
||
RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyAccounting,
|
||
TRUE,
|
||
REG_NOTIFY_CHANGE_LAST_SET,
|
||
gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION1],
|
||
TRUE );
|
||
|
||
RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyAuthentication,
|
||
TRUE,
|
||
REG_NOTIFY_CHANGE_LAST_SET,
|
||
gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION2],
|
||
TRUE );
|
||
while( TRUE )
|
||
{
|
||
dwSignaledEvent = WaitForMultipleObjectsEx(
|
||
NUM_DDM_EVENTS
|
||
+ ( gblDeviceTable.NumDeviceBuckets * 3 ),
|
||
gblSupervisorEvents,
|
||
FALSE,
|
||
INFINITE,
|
||
TRUE);
|
||
|
||
if ( ( dwSignaledEvent == 0xFFFFFFFF ) ||
|
||
( dwSignaledEvent == WAIT_TIMEOUT ) )
|
||
{
|
||
DDMTRACE2("WaitForMultipleObjectsEx returned %d, GetLastError=%d",
|
||
dwSignaledEvent, GetLastError() );
|
||
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// DDM has terminated so return
|
||
//
|
||
|
||
if ( dwSignaledEvent == DDM_EVENT_SVC_TERMINATED )
|
||
{
|
||
LPDWORD lpdwNumThreadsRunning =
|
||
gblDDMConfigInfo.lpdwNumThreadsRunning;
|
||
|
||
//
|
||
// If we were running and we are now shutting down, clean up
|
||
// gracefully
|
||
//
|
||
|
||
if ( gblDDMConfigInfo.pServiceStatus->dwCurrentState
|
||
== SERVICE_STOP_PENDING )
|
||
{
|
||
DDMCleanUp();
|
||
}
|
||
|
||
//
|
||
// Decrease the count for this thread
|
||
//
|
||
|
||
InterlockedDecrement( lpdwNumThreadsRunning );
|
||
|
||
return( NO_ERROR );
|
||
}
|
||
|
||
//
|
||
// invoke the handler associated with the signaled event
|
||
//
|
||
|
||
if ( dwSignaledEvent < NUM_DDM_EVENTS )
|
||
{
|
||
//
|
||
// Some DDM event
|
||
//
|
||
|
||
gblEventHandlerTable[dwSignaledEvent].EventHandler();
|
||
}
|
||
else if ( dwSignaledEvent < ( NUM_DDM_EVENTS
|
||
+ gblDeviceTable.NumDeviceBuckets ) )
|
||
{
|
||
//
|
||
// The event was a RASMAN event
|
||
//
|
||
|
||
RmEventHandler( dwSignaledEvent );
|
||
}
|
||
else if ( dwSignaledEvent < ( NUM_DDM_EVENTS
|
||
+ gblDeviceTable.NumDeviceBuckets * 2 ) )
|
||
{
|
||
//
|
||
// A frame was received on a port
|
||
//
|
||
|
||
RmRecvFrameEventHandler( dwSignaledEvent );
|
||
}
|
||
else if ( dwSignaledEvent != WAIT_IO_COMPLETION )
|
||
{
|
||
//
|
||
// We got a disconnect on a dialed out port
|
||
//
|
||
|
||
RasApiDisconnectHandler( dwSignaledEvent );
|
||
}
|
||
}
|
||
|
||
return( NO_ERROR );
|
||
}
|
||
|
||
//***
|
||
//
|
||
// Function: SecurityDllEventHandler
|
||
//
|
||
// Descr: This will handle all events from the 3rd party security Dll.
|
||
// Either the security dialog with the client completed
|
||
// successfully, in which case we continue on with the connection,
|
||
// or we log the error and bring down the line.
|
||
//
|
||
//***
|
||
|
||
VOID
|
||
SecurityDllEventHandler(
|
||
VOID
|
||
)
|
||
{
|
||
LPWSTR auditstrp[3];
|
||
SECURITY_MESSAGE message;
|
||
PDEVICE_OBJECT pDevObj;
|
||
DWORD dwBucketIndex;
|
||
WCHAR wchUserName[UNLEN+1];
|
||
|
||
//
|
||
// loop to get all messages
|
||
//
|
||
|
||
while( ServerReceiveMessage( MESSAGEQ_ID_SECURITY, (BYTE *) &message ) )
|
||
{
|
||
|
||
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
|
||
//
|
||
// identify the message recipient
|
||
//
|
||
|
||
if ( ( pDevObj = DeviceObjGetPointer( message.hPort ) ) == NULL )
|
||
{
|
||
|
||
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// action on the message type
|
||
//
|
||
|
||
switch( message.dwMsgId )
|
||
{
|
||
|
||
case SECURITYMSG_SUCCESS:
|
||
|
||
//
|
||
// Stop timer for 3rd party security
|
||
//
|
||
|
||
TimerQRemove( (HANDLE)pDevObj->hPort, SvSecurityTimeout );
|
||
|
||
RasFreeBuffer( pDevObj->pRasmanSendBuffer );
|
||
|
||
pDevObj->pRasmanSendBuffer = NULL;
|
||
|
||
//
|
||
// copy the user name
|
||
//
|
||
|
||
MultiByteToWideChar( CP_ACP,
|
||
0,
|
||
message.UserName,
|
||
-1,
|
||
pDevObj->wchUserName,
|
||
UNLEN+1 );
|
||
|
||
//
|
||
// copy the domain name
|
||
//
|
||
|
||
MultiByteToWideChar( CP_ACP,
|
||
0,
|
||
message.Domain,
|
||
-1,
|
||
pDevObj->wchDomainName,
|
||
DNLEN+1 );
|
||
|
||
pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
|
||
|
||
//
|
||
// Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
|
||
// RmEventHandler
|
||
//
|
||
|
||
RasPortConnectComplete(pDevObj->hPort);
|
||
|
||
dwBucketIndex = DeviceObjHashPortToBucket( pDevObj->hPort );
|
||
|
||
SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
|
||
|
||
DDM_PRINT(
|
||
gblDDMConfigInfo.dwTraceId,
|
||
TRACE_FSM,
|
||
"SecurityDllEventHandler: Security DLL success \n" );
|
||
|
||
break;
|
||
|
||
case SECURITYMSG_FAILURE:
|
||
|
||
//
|
||
// Log the fact that the use failed to pass 3rd party security.
|
||
//
|
||
|
||
MultiByteToWideChar( CP_ACP,
|
||
0,
|
||
message.UserName,
|
||
-1,
|
||
wchUserName,
|
||
UNLEN+1 );
|
||
|
||
auditstrp[0] = wchUserName;
|
||
auditstrp[1] = pDevObj->wchPortName;
|
||
|
||
DDMLogError( ROUTERLOG_SEC_AUTH_FAILURE, 2, auditstrp, NO_ERROR );
|
||
|
||
//
|
||
// Hang up the line
|
||
//
|
||
|
||
DDM_PRINT(
|
||
gblDDMConfigInfo.dwTraceId,
|
||
TRACE_FSM,
|
||
"SecurityDllEventHandler:Security DLL failure %s\n",
|
||
message.UserName );
|
||
|
||
if ( pDevObj->SecurityState == DEV_OBJ_SECURITY_DIALOG_ACTIVE )
|
||
{
|
||
DevStartClosing(pDevObj);
|
||
}
|
||
else if ( pDevObj->SecurityState==DEV_OBJ_SECURITY_DIALOG_STOPPING )
|
||
{
|
||
pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
|
||
|
||
DevCloseComplete(pDevObj);
|
||
}
|
||
|
||
break;
|
||
|
||
case SECURITYMSG_ERROR:
|
||
|
||
auditstrp[0] = pDevObj->wchPortName;
|
||
|
||
DDMLogErrorString( ROUTERLOG_SEC_AUTH_INTERNAL_ERROR, 1, auditstrp,
|
||
message.dwError, 1);
|
||
|
||
DDM_PRINT(
|
||
gblDDMConfigInfo.dwTraceId,
|
||
TRACE_FSM,
|
||
"SecurityDllEventHandler:Security DLL failure %x\n",
|
||
message.dwError );
|
||
|
||
if ( pDevObj->SecurityState == DEV_OBJ_SECURITY_DIALOG_ACTIVE )
|
||
{
|
||
DevStartClosing(pDevObj);
|
||
}
|
||
else if ( pDevObj->SecurityState==DEV_OBJ_SECURITY_DIALOG_STOPPING )
|
||
{
|
||
pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
|
||
|
||
DevCloseComplete(pDevObj);
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
RTASSERT(FALSE);
|
||
break;
|
||
}
|
||
|
||
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
||
}
|
||
}
|