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