|
|
/*******************************************************************/ /* Copyright(c) 1992 Microsoft Corporation */ /*******************************************************************/
//***
//
// Filename: ddmif.c
//
// Description: message based communication code
//
// Author: Stefan Solomon (stefans) June 24, 1992.
//
// Revision History:
//
//***
#include "ddm.h"
#include <ddmif.h>
#include <string.h>
#include <raserror.h>
#include <rasppp.h>
//
// Message element definition
//
typedef struct _MESSAGE_Q_OBJECT { struct _MESSAGE_Q_OBJECT * pNext;
MESSAGE MsgBuffer;
} MESSAGE_Q_OBJECT, *PMESSAGE_Q_OBJECT;
//
// Message queue header definition
//
typedef struct _MESSAGE_Q { MESSAGE_Q_OBJECT * pQHead;
MESSAGE_Q_OBJECT * pQTail;
HANDLE hEvent; // Signaled when enqueueing a new message
DWORD dwLength; // size of message data for each node in Q
CRITICAL_SECTION CriticalSection; // Mutex around this Q
} MESSAGE_Q, *PMESSAGE_Q;
BOOL gfMessageQueueInitialized = FALSE;
//
// Message queue table
//
static MESSAGE_Q MessageQ[MAX_MSG_QUEUES];
VOID SendPppMessageToDDM( IN PPP_MESSAGE * pPppMsg ) { ServerSendMessage( MESSAGEQ_ID_PPP, (PBYTE)pPppMsg ); }
VOID RasSecurityDialogComplete( IN SECURITY_MESSAGE *pSecurityMessage ) { ServerSendMessage( MESSAGEQ_ID_SECURITY, (PBYTE)pSecurityMessage ); }
//*** Message Debug Printing Tables ***
typedef struct _MSGDBG { WORD id; LPSTR txtp;
} MSGDBG, *PMSGDBG;
enum { MSG_SEND, MSG_RECEIVE };
MSGDBG dstsrc[] = { { MESSAGEQ_ID_SECURITY, "Security" }, { MESSAGEQ_ID_PPP, "PPP" }, { 0xffff, NULL } };
MSGDBG authmsgid[] = { { AUTH_DONE, "AUTH_DONE" }, { AUTH_FAILURE, "AUTH_FAILURE" }, { AUTH_STOP_COMPLETED, "AUTH_STOP_COMPLETED" }, { AUTH_PROJECTION_REQUEST, "AUTH_PROJECTION_REQUEST" }, { AUTH_CALLBACK_REQUEST, "AUTH_CALLBACK_REQUEST" }, { AUTH_ACCT_OK, "AUTH_ACCT_OK" }, { 0xffff, NULL } };
MSGDBG pppmsgid[] = { { PPPMSG_Stopped, "PPPMSG_Stopped" }, { PPPDDMMSG_PppDone, "PPPDDMMSG_PppDone" }, { PPPDDMMSG_PppFailure, "PPPDDMMSG_PppFailure" }, { PPPDDMMSG_CallbackRequest, "PPPDDMMSG_CallbackRequest" }, { PPPDDMMSG_Authenticated, "PPPDDMMSG_Authenticated" }, { PPPDDMMSG_Stopped, "PPPDDMMSG_Stopped" }, { PPPDDMMSG_NewLink, "PPPDDMMSG_NewLink" }, { PPPDDMMSG_NewBundle, "PPPDDMMSG_NewBundle" }, { PPPDDMMSG_NewBapLinkUp, "PPPDDMMSG_NewBapLinkUp" }, { PPPDDMMSG_BapCallbackRequest, "PPPDDMMSG_BapCallbackRequest" }, { PPPDDMMSG_PnPNotification, "PPPDDMMSG_PnPNotification" }, { PPPDDMMSG_PortCleanedUp, "PPPDDMMSG_PortCleanedUp" }, { 0xffff, NULL } };
MSGDBG opcodestr[] = { { MSG_SEND, "ServerSendMessage" }, { MSG_RECEIVE, "ServerReceiveMessage" }, { 0xffff, NULL } };
MSGDBG securitymsgid[] = { { SECURITYMSG_SUCCESS, "SECURITYMSG_SUCCESS" }, { SECURITYMSG_FAILURE, "SECURITYMSG_FAILURE" }, { SECURITYMSG_ERROR, "SECURITYMSG_ERROR" }, { 0xffff, NULL } };
char * getstring( IN WORD id, IN PMSGDBG msgdbgp ) { char *strp; PMSGDBG mdp;
for (mdp = msgdbgp; mdp->id != 0xffff; mdp++) { if (mdp->id == id) { strp = mdp->txtp; return(strp); } }
RTASSERT(FALSE); return(NULL); }
//***
//
// Function: msgdbgprint
//
// Descr: prints each message passing through the message module
//
//***
VOID msgdbgprint( IN WORD opcode, IN WORD src, IN BYTE *buffp ) { char *srcsp, *msgidsp, *operation; HPORT hport = 0;
//
// identify message source. This gives us the clue on the message
// structure.
//
switch (src) { case MESSAGEQ_ID_SECURITY: msgidsp = getstring((WORD)((SECURITY_MESSAGE *) buffp)->dwMsgId, securitymsgid); hport = ((SECURITY_MESSAGE *) buffp)->hPort; break;
case MESSAGEQ_ID_PPP: msgidsp = getstring((WORD)((PPP_MESSAGE *) buffp)->dwMsgId, pppmsgid ); hport = ((PPP_MESSAGE *) buffp)->hPort; break;
default:
RTASSERT(FALSE); }
srcsp = getstring(src, dstsrc); operation = getstring(opcode, opcodestr);
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_MESSAGES, "%s on port/connection: %x from: %s Message: %s", operation, hport, srcsp, msgidsp);
}
//***
//
// Function: InitializeMessageQs
//
// Returns: None
//
// Description:Initializes the message queue headers
//
//***
VOID InitializeMessageQs( IN HANDLE hEventSecurity, IN HANDLE hEventPPP ) { DWORD dwIndex;
MessageQ[MESSAGEQ_ID_SECURITY].hEvent = hEventSecurity; MessageQ[MESSAGEQ_ID_PPP].hEvent = hEventPPP;
MessageQ[MESSAGEQ_ID_SECURITY].dwLength = sizeof(SECURITY_MESSAGE); MessageQ[MESSAGEQ_ID_PPP].dwLength = sizeof(PPP_MESSAGE);
for ( dwIndex = 0; dwIndex < MAX_MSG_QUEUES; dwIndex++ ) { MessageQ[dwIndex].pQHead = NULL; MessageQ[dwIndex].pQTail = NULL;
InitializeCriticalSection( &(MessageQ[dwIndex].CriticalSection) ); }
gfMessageQueueInitialized = TRUE; }
//***
//
// Function: DeleteMessageQs
//
// Returns: None
//
// Description:DeInitializes the message queue headers
//
//***
VOID DeleteMessageQs( VOID ) { DWORD dwIndex; IN BYTE * pMessage;
if(!gfMessageQueueInitialized) { return; }
//
// Flush the queues
//
for ( dwIndex = 0; dwIndex < MAX_MSG_QUEUES; dwIndex++ ) { DeleteCriticalSection( &(MessageQ[dwIndex].CriticalSection) ); }
gfMessageQueueInitialized = FALSE; }
//***
//
// Function: ServerSendMessage
//
// Descr: Sends message from specified server component
// source to server component dst.
//
// Returns: NO_ERROR - success
// else - failure
//
//***
DWORD ServerSendMessage( IN MESSAGEQ_ID MsgQId, IN BYTE * pMessage ) { MESSAGE_Q_OBJECT * pMsgQObj;
//
// Make sure DDM is running before accessing any data structure
//
if ( gblDDMConfigInfo.pServiceStatus == NULL ) { return( ERROR_DDM_NOT_RUNNING ); }
switch( gblDDMConfigInfo.pServiceStatus->dwCurrentState ) { case SERVICE_STOP_PENDING:
//
// Allow only PPP stopping messages
//
if ( MsgQId == MESSAGEQ_ID_PPP ) { if ((((PPP_MESSAGE *)pMessage)->dwMsgId == PPPDDMMSG_Stopped ) || (((PPP_MESSAGE *)pMessage)->dwMsgId == PPPDDMMSG_PppFailure)|| (((PPP_MESSAGE *)pMessage)->dwMsgId == PPPDDMMSG_PortCleanedUp)) { break; } }
//
// Otherwise fall thru
//
case SERVICE_START_PENDING: case SERVICE_STOPPED:
return( ERROR_DDM_NOT_RUNNING );
default: break; }
EnterCriticalSection( &(MessageQ[MsgQId].CriticalSection) );
//
// allocate a message structure
//
pMsgQObj = (MESSAGE_Q_OBJECT *)LOCAL_ALLOC( LPTR, sizeof(MESSAGE_Q_OBJECT));
if ( pMsgQObj == (MESSAGE_Q_OBJECT *)NULL ) { //
// can't allocate message buffer
//
RTASSERT(FALSE);
LeaveCriticalSection( &(MessageQ[MsgQId].CriticalSection) );
return( GetLastError() ); }
//
// copy the message
//
CopyMemory( &(pMsgQObj->MsgBuffer), pMessage, MessageQ[MsgQId].dwLength );
//
// Insert it in the Q
//
if ( MessageQ[MsgQId].pQHead == (MESSAGE_Q_OBJECT *)NULL ) { MessageQ[MsgQId].pQHead = pMsgQObj; } else { MessageQ[MsgQId].pQTail->pNext = pMsgQObj; }
MessageQ[MsgQId].pQTail = pMsgQObj; pMsgQObj->pNext = NULL;
//
// and set appropriate event
//
SetEvent( MessageQ[MsgQId].hEvent );
msgdbgprint( MSG_SEND, (WORD)MsgQId, pMessage );
LeaveCriticalSection( &(MessageQ[MsgQId].CriticalSection) );
return( NO_ERROR ); }
//***
//
// Function: ServerReceiveMessage
//
// Descr: Gets one message from the specified message queue
//
// Returns: TRUE - message fetched
// FALSE - queue empty
//
//***
BOOL ServerReceiveMessage( IN MESSAGEQ_ID MsgQId, IN BYTE * pMessage ) { MESSAGE_Q_OBJECT * pMsgQObj; HLOCAL err;
EnterCriticalSection( &(MessageQ[MsgQId].CriticalSection) );
if ( MessageQ[MsgQId].pQHead == (MESSAGE_Q_OBJECT *)NULL ) { //
// queue is empty
//
LeaveCriticalSection( &(MessageQ[MsgQId].CriticalSection) );
return( FALSE ); }
pMsgQObj = MessageQ[MsgQId].pQHead;
MessageQ[MsgQId].pQHead = pMsgQObj->pNext;
if ( MessageQ[MsgQId].pQHead == (MESSAGE_Q_OBJECT *)NULL ) { MessageQ[MsgQId].pQTail = (MESSAGE_Q_OBJECT *)NULL; }
//
// copy the message in the caller's buffer
//
CopyMemory( pMessage, &(pMsgQObj->MsgBuffer), MessageQ[MsgQId].dwLength );
//
// free the message buffer
//
LOCAL_FREE( pMsgQObj );
msgdbgprint( MSG_RECEIVE, (WORD)MsgQId, pMessage );
LeaveCriticalSection( &(MessageQ[MsgQId].CriticalSection) );
return( TRUE ); }
|