449 lines
9.2 KiB
C
449 lines
9.2 KiB
C
/*******************************************************************/
|
||
/* 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;
|
||
|
||
//
|
||
// 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) );
|
||
}
|
||
}
|
||
|
||
//***
|
||
//
|
||
// Function: DeleteMessageQs
|
||
//
|
||
// Returns: None
|
||
//
|
||
// Description:DeInitializes the message queue headers
|
||
//
|
||
//***
|
||
VOID
|
||
DeleteMessageQs(
|
||
VOID
|
||
)
|
||
{
|
||
DWORD dwIndex;
|
||
IN BYTE * pMessage;
|
||
|
||
//
|
||
// Flush the queues
|
||
//
|
||
|
||
for ( dwIndex = 0; dwIndex < MAX_MSG_QUEUES; dwIndex++ )
|
||
{
|
||
DeleteCriticalSection( &(MessageQ[dwIndex].CriticalSection) );
|
||
}
|
||
}
|
||
|
||
//***
|
||
//
|
||
// 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 );
|
||
}
|
||
|