Receiving Messages by Using a Transport Provider

Receiving Messages by Using a Transport Provider

Before you can receive messages by using a transport provider, you must initialize the transport provider to establish a connection between MAPI and the transport provider. You must also set up the transport provider so that MAPI knows what types of addresses the transport provider accepts. For more information, see Initializing a Transport Provider and Setting Up a Transport Provider.

Once the transport provider is ready to transmit messages, you must implement the IXPLogon::Poll function to notify MAPI of messages that are ready to be received. If there are inbound messages ready to be processed, the IXPLogon::StartMessage function initiates the transfer of the messages from the transport provider to MAPI.

In this topic these functions are demonstrated by using code examples from the MRXP Sample Transport Provider. The MRXP Sample Transport Provider implements a shared network file system transport provider using a UNC share or a local folder. For more information about downloading and installing the MRXP Sample Transport Provider, see Installing the Sample Transport Provider.

While you are receiving messages by using the transport provider, you can also send messages by using the transport provider. For more information, see Sending Messages by Using a Transport Provider.

If you stop using the transport provider, you must follow the proper procedures for shutting down and logging off the transport provider. For more information, see Shutting Down a Transport Provider.

Poll Routine

MAPI calls the IXPLogon::Poll function to determine whether the transport provider has inbound messages that are ready to be processed. If there are not any inbound messages waiting, the value 0 is returned in the lpulIncoming parameter. If there are inbound messages ready to be processed, the value 1 is returned.

CXPLogon::Poll() Example

  STDMETHODIMP CXPLogon::Poll(ULONG FAR *	lpulIncoming)
{
    Log(true, _T("CXPLogon::Poll function called\n"));
if (!lpulIncoming)
    return MAPI_E_INVALID_PARAMETER;

HRESULT hRes = S_OK;
*lpulIncoming = 0;

if (m_ulStatusBits & STATUS_INBOUND_ENABLED)
{
    hRes = NewMailWaiting(NULL, NULL);
    if (S_FALSE == hRes)
    {
        // No messages waiting
        hRes = S_OK;
    }
    else if (SUCCEEDED(hRes))
    {
        // Messages waiting
        Log(true, _T("CXPLogon::Poll: New messages are available\n"));
        *lpulIncoming = 1;
    }
    else
    {
        Log(true, _T("CXPLogon::Poll: NewMailWaiting returned an error: " +
            "0x%08X\n"), hRes);
    }
}
return hRes;

}

Start Message Routine

If the return value from IXPLogon::Poll indicates that there are inbound messages waiting, MAPI calls IXPLogon::StartMessage to initiate the transfer of the messages from the transport provider to MAPI. The lpMessage parameter points to the object that represents the incoming message. The function uses this parameter access the message and prepare it for delivery.

initiate

CXPLogon::StartMessage() Example

  STDMETHODIMP CXPLogon::StartMessage(
    ULONG /*ulFlags*/,
    LPMESSAGE lpMessage,
    ULONG FAR * lpulMsgRef)
{
    Log(true, _T("CXPLogon::StartMessage function called\n"));
if (!lpMessage || !lpulMsgRef || !m_pProps)
    return MAPI_E_INVALID_PARAMETER;
if (m_ulStatusBits & STATUS_INBOUND_ACTIVE)
{
    Log(true, _T("CXPLogon::StartMessage: called while we're already processing. "
        + "Returning MAPI_E_BUSY\n"));
    return MAPI_E_BUSY;
}

HRESULT hRes = S_OK;
AddStatusBits(STATUS_INBOUND_ACTIVE);
hRes = UpdateStatusRow();
if (FAILED(hRes))
{
    Log(true, _T("CXPLogon::StartMessage: UpdateStatusRow returned an error: "
        + "0x%08X\n"), hRes);
    RemoveStatusBits(STATUS_INBOUND_ACTIVE);
    return hRes;
}

// See if there is a message to deliver
LPTSTR pszNewMailFile = NULL;
FILETIME ftDelivered = {0};
hRes = NewMailWaiting(&pszNewMailFile, &ftDelivered);
if (S_OK == hRes && pszNewMailFile)
{
    Log(true, _T("CXPLogon::StartMessage: processing %s\n"), pszNewMailFile);

    hRes = LoadFromMSG(pszNewMailFile, lpMessage);
    if (SUCCEEDED(hRes))
    {
        // Set the Received By properties and Delivery Time properties.
        SPropValue spvTransportStamped[NUM_XP_SETPROPS] = {0};

        spvTransportStamped[SENDER_DISPLAY_NAME].ulPropTag = 
            PR_RECEIVED_BY_NAME_A;
        spvTransportStamped[SENDER_DISPLAY_NAME].Value.lpszA = 
            m_pIdentityProps[IDENTITY_DISPLAY_NAME].Value.lpszA;

        spvTransportStamped[SENDER_EMAIL_ADDRESS].ulPropTag = 
            PR_RECEIVED_BY_EMAIL_ADDRESS_A;
        spvTransportStamped[SENDER_EMAIL_ADDRESS].Value.lpszA = 
            m_pProps[CLIENT_INBOX].Value.lpszA;

        spvTransportStamped[SENDER_ADDRTYPE].ulPropTag = 
            PR_RECEIVED_BY_ADDRTYPE_A;
        spvTransportStamped[SENDER_ADDRTYPE].Value.lpszA = 
            MRXP_ADDRTYPE_A;

        spvTransportStamped[SENDER_SEARCH_KEY].ulPropTag = 
            PR_RECEIVED_BY_SEARCH_KEY;
        spvTransportStamped[SENDER_SEARCH_KEY].Value.bin = 
            m_pIdentityProps[IDENTITY_SEARCH_KEY].Value.bin;

        spvTransportStamped[SENDER_ENTRYID].ulPropTag = 
            PR_RECEIVED_BY_ENTRYID;
        spvTransportStamped[SENDER_ENTRYID].Value.bin = 
            m_pIdentityProps[IDENTITY_ENTRYID].Value.bin;

        spvTransportStamped[MSG_RECEIVE_TIME].ulPropTag = 
            PR_MESSAGE_DELIVERY_TIME;
        spvTransportStamped[MSG_RECEIVE_TIME].Value.ft = ftDelivered;

        spvTransportStamped[MSG_FLAGS].ulPropTag = PR_MESSAGE_FLAGS;
        spvTransportStamped[MSG_FLAGS].Value.ul = 0;

        hRes = lpMessage->SetProps(NUM_XP_SETPROPS, spvTransportStamped, 
            NULL);
        if (SUCCEEDED(hRes))
        {
            hRes = lpMessage->SaveChanges(0);
            if (SUCCEEDED(hRes))
            {
                BOOL bRet = DeleteFile(pszNewMailFile);
                if (!bRet)
                {
                    Log(true, _T("CXPLogon::StartMessage: DeleteFile returned an error: "
                        + "0x%08X\n"), GetLastError());
                }
            }
            else
            {
                Log(true, _T("CXPLogon::StartMessage: SaveChanges returned an error:"
                    + " 0x%08X\n"), hRes);
            }
        }
        else
        {
            Log(true, _T("CXPLogon::StartMessage: SetProps returned an error: "
                + "0x%08X\n"), hRes);
        }
    }
    else
    {
        Log(true, _T("CXPLogon::StartMessage: LoadFromMSG returned an error: "
            + "0x%08X\n"), hRes);
    }
}
else if (S_FALSE == hRes)
{
    Log(true, _T("CXPLogon::StartMessage: No message to deliver...exiting\n"));
}
else
{
    Log(true, _T("CXPLogon::StartMessage: NewMailWaiting returned an error: "
        + "0x%08X\n"), hRes);
}

MyFreeBuffer(pszNewMailFile);
HRESULT hResTemp = S_OK;
RemoveStatusBits(STATUS_INBOUND_ACTIVE);
hResTemp = UpdateStatusRow();
if (FAILED(hResTemp))
{
    Log(true, _T("CXPLogon::StartMessage: UpdateStatusRow returned an error: "
        + "0x%08X\n"), hResTemp);
}
if (FAILED(hRes))
{
    m_pMAPISup->SpoolerNotify(NOTIFY_CRITICAL_ERROR, NULL);
    ULONG ulIncoming = 0;
    Poll(&ulIncoming);
}
return hRes;

}

See Also

About the Sample Transport Provider

Installing the Sample Transport Provider

Initializing a Transport Provider

Setting Up a Transport Provider

Sending Messages by Using a Transport Provider

Shutting Down a Transport Provider