Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Writing MSMQ Server for MAPI Transport Provider  
Nik Okuntseff  MS Exchange Server Programming 

Writing MSMQ Server for MAPI Transport Provider

The following sample (MSMQ/XPPServer) is a simple MSMQ server application, which reads messages from MSMQ MAPI Transport Provider outbound queue. For the sake of simplicity the algorithm is extremely simple: open the queue, then read messages from it in an infinite loop. If a message is read, then inform the user. The code is straightforward:

#include <windows.h>
#include "mq.h"

int main(void)
{
    /*
     * Algorithm:
     *  1. Open the outgoing queue.
     *  2. Do an infinite loop:
     *   Read a message from outgoing queue.
     *   Pop-up a message box to the user.
     */

    /*
     * I assume this queue name. Replace this as necessary.
     * You need to create this queue manually before being able to send
     * messages to it via MSMQ MAPI Transport. Make sure its type
     * ID is {5EADC0D0-7182-11CF-A8FF-0020AFB8FB50}
     */
    #define MY_OUT_QUEUE_PATHNAME L"mig\\xpp_outbound"
 
    // Determine format name of the outgoing queue
    wchar_t wcsQueueFormatName[MAX_PATH];
    DWORD dwSize = MAX_PATH;
    HRESULT hRes = ::MQPathNameToFormatName(MY_OUT_QUEUE_PATHNAME,
           wcsQueueFormatName,
           &dwSize);
    if (FAILED(hRes))
        throw (-1);

    // Open the outgoing queue.
    QUEUEHANDLE hOutQueue = NULL;
    hRes = ::MQOpenQueue(wcsQueueFormatName,
         MQ_RECEIVE_ACCESS,
         MQ_DENY_RECEIVE_SHARE,
         &hOutQueue);
    if (FAILED(hRes))
        throw (-1);

    // Prepare our MQMSGPROPS struct
    MQMSGPROPS MsgProps;

    // We'll ask only for message bodies. Arrays of size 1 are enough.
    MQPROPVARIANT aVariant[1];
    MSGPROPID aPropId[1];

    #define MSG_BODY_LEN 2048 // For short messages this is enough
    unsigned char ucMsgBody[MSG_BODY_LEN];

    // Set the PROPID_M_BODY property.
    aPropId[0] = PROPID_M_BODY;    // PropId
    aVariant[0].vt = VT_VECTOR | VT_UI1; // Type
    aVariant[0].caub.cElems = MSG_BODY_LEN; // Buffer size.
    aVariant[0].caub.pElems = ucMsgBody; // Buffer

    // Set the MQMSGPROPS structure
    MsgProps.cProp = 1;    // Number of properties.
    MsgProps.aPropID = aPropId;  // Ids of properties.
    MsgProps.aPropVar = aVariant; // Values of properties.
    MsgProps.aStatus = NULL;  // No error report.
 
    // This is our infinite loop
    while (TRUE)
    {
        // Read one message from the queue
        hRes = ::MQReceiveMessage(hOutQueue,  // Handle to the queue
                1 * 60 * 1000,  // Timeout value in ms (1 min)
                MQ_ACTION_RECEIVE, // Action
                &MsgProps,   // Properties to retrieve
                NULL,    // Must be NULL for synchronous receive
                NULL,    // Must be NULL for synchronous receive
                NULL,    // No cursor
                MQ_NO_TRANSACTION); // No transaction
        if (SUCCEEDED(hRes))
            ::MessageBox(NULL, "Message retrieved from MSMQ MAPI transport!", "XPPServer", MB_OK);
    }

    return 0;
}
 

[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff