windows-nt/Source/XPSP1/NT/net/rras/ras/ddm/ddmif.c
2020-09-26 16:20:57 +08:00

449 lines
9.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*******************************************************************/
/* 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 );
}