// ************************************************************
// MAPIRULE.CPP
//
// Sample implementation of a message Rule Client
//
// Copyright 1986-2002 Microsoft Corporation, All Rights Reserved
//
#define INITGUID
#include <windows.h>
#include <assert.h>
#include "cemapi.h"
#define MMBUFSIZE 1024
int g_cServerLocks = 0;
// Declare a structure to pass an SMS message to the client process. For this sample we
// only pass the message body and the phone number but it would be possible to store
// all kinds of information related to the SMS message.
typedef struct {
WCHAR g_szMessageBody[255];
WCHAR g_szPhoneNr[255];
} SMS_BUFFER;
typedef SMS_BUFFER *PSMS_BUFFER;
// Declare some handles to setup a memory mapped file used to pass information to the
// client process.
HANDLE g_hMMObj = NULL;
PSMS_BUFFER g_pSmsBuffer = NULL;
// Declare handles for the synchronization objects inside the IMailRuleClient object.
HANDLE g_hSmsAvailableEvent = NULL;
HANDLE g_hMutex = NULL;
// {3AB4C10E-673C-494c-98A2-CC2E91A48115}
DEFINE_GUID(CLSID_MapiRuleSample, 0x3ab4c10e, 0x673c, 0x494c, 0x98, 0xa2, 0xcc, 0x2e, 0x91, 0xa4, 0x81, 0x15);
/* Add to apps.reg: NOTE: calling DllRegisterServer will take care of this programatically
[HKEY_CLASSES_ROOT\CLSID\{3AB4C10E-673C-494c-98A2-CC2E91A48115}\InProcServer32]
@="mapirule.dll"
*/
/*
Add this line too:
[HKEY_LOCAL_MACHINE\Software\Microsoft\Inbox\Svc\SMS\Rules]
"{3AB4C10E-673C-494c-98A2-CC2E91A48115}"=dword:1
*/
// **************************************************************************
// Function Name: DeleteMessage
//
// Purpose: Delete a MAPI message
// Arguments:
// IN IMsgStore* pMsgStore - Message Store to delete from
// IN IMessage* pMsg - ptr to message to be deleted
// IN ULONG cbMsg - The size of lpMsg, in bytes
// IN LPENTRYID lpMsg - The ENTRYID of the message
// IN ULONG cbDestFolder - The size of lpDestFolder, in bytes
// IN LPENTRYID lpDestFolder - The ENTRYID of the folder that incoming
// messages are moved to
// OUT ULONG *pulEventType - Combination of bit flags indicating the type if
// action performed on the message, deletion in this case
// OUT MRCHANDLED *pHandled - Indicates the type of handling that occurred,
// in this case we mark the message as handled, and do not pass it on
//
// Return Values: HRESULT depending on success of MAPI operations
// Side effects:
// Description:
// This function deletes a given message from a given folder and
// sets the proper notification event
HRESULT DeleteMessage(IMsgStore *pMsgStore, IMessage *pMsg, ULONG cbMsg, LPENTRYID lpMsg, ULONG cbDestFolder,
LPENTRYID lpDestFolder, ULONG *pulEventType, MRCHANDLED *pHandled)
{
HRESULT hr = S_OK;
ENTRYLIST lst;
SBinary sbin;
IMAPIFolder *pFolder = NULL;
// Delete it
hr = pMsgStore->OpenEntry(cbDestFolder, lpDestFolder, NULL, 0, NULL, (LPUNKNOWN *) &pFolder);
if (FAILED(hr))
{
RETAILMSG(TRUE, (TEXT("Couldn't get the folder!\r\n")));
goto Exit;
}
lst.cValues = 1;
sbin.cb = cbMsg;
sbin.lpb = (LPBYTE) lpMsg;
lst.lpbin = &sbin;
hr = pFolder->DeleteMessages(&lst, NULL, NULL, 0);
if (FAILED(hr))
{
RETAILMSG(TRUE, (TEXT("Couldn't delete messages!\r\n")));
goto Exit;
}
// Notification object lets listeners know we deleted this
*pulEventType = fnevObjectDeleted;
// Mark as handled and don't pass on
*pHandled = MRC_HANDLED_DONTCONTINUE;
Exit:
if (pFolder)
{
pFolder->Release();
}
return hr;
}
// ************************************************************
// Class CMailRuleClient - Implementation of IMailRuleClient
//
// Inheritance:
// IMailRuleClient IUnknown (Abstract)
//
// Purpose:
// This class serves as implementation for the IMailRuleClient
// interface and provides our Rule Client functionality.
// The Initialize method sets our permissions to interact
// with the message store, and the ProcesseMessage method
// defines how we handle incoming messages
//
// ************************************************************
class CMailRuleClient : public IMailRuleClient
{
public:
CMailRuleClient();
~CMailRuleClient();
// IUnknown
STDMETHOD (QueryInterface)(REFIID iid, LPVOID *ppv);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
// IMailRuleClient
MAPIMETHOD(Initialize)(
IMsgStore *pMsgStore,
MRCACCESS *pmaDesired
);
MAPIMETHOD(ProcessMessage)(
IMsgStore *pMsgStore,
ULONG cbMsg,
LPENTRYID lpMsg,
ULONG cbDestFolder,
LPENTRYID lpDestFolder,
ULONG *pulEventType,
MRCHANDLED *pHandled
);
private:
long m_cRef;
};
// ************************************************************
// Class CFactory - Class factory for CMailRuleClient objects
//
// Inheritance:
// IClassFactory IUnknown
//
// Purpose:
// This class provides a standard COM class factory implementation
// for CMailRuleClient
//
// ************************************************************
class CFactory : public IClassFactory
{
public:
CFactory();
~CFactory();
// IUnknown
STDMETHOD (QueryInterface)(REFIID iid, LPVOID *ppv);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
// IClassFactory interfaces
STDMETHOD (CreateInstance)(IUnknown *pUnknownOuter, const IID& iid, LPVOID *ppv);
STDMETHOD (LockServer)(BOOL bLock);
private:
long m_cRef;
};
// **************************************************************************
// Function Name: CFactory
// Purpose: Initializes CFactory object
// Arguments:
// Return Values:
// Side effects:
// Description:
// Constructor for CFactory class. Initializes class members.
CFactory::CFactory()
{
m_cRef = 1;
}
// **************************************************************************
// Function Name: ~CFactory
//
// Purpose: Cleans up CFactory object
// Arguments:
// Return Values:
// Side effects:
// Description:
// Destructor for CFactory object
CFactory::~CFactory()
{
}
// **************************************************************************
// Function Name: QueryInterface
// Purpose: Obtains caller's desired interface pointer if it is supported
// Arguments:
// IN IID& iid - Identifier for desired interface
// OUT LPVOID *ppv - pointer to desired interface pointer
// Return Values: HRESULT
// E_NOINTERFACE: the requested interface is not supported
// E_INVALIDARG: bad reference for out param
// Side effects:
// Description:
// Standard implementation of COM IUnknown::QueryInterface
STDMETHODIMP CFactory::QueryInterface(const IID& iid, LPVOID *ppv)
{
HRESULT hr = E_NOINTERFACE;
if (!ppv)
{
return E_INVALIDARG;
}
if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
{
*ppv = (LPVOID) this;
}
else
{
*ppv = NULL;
}
if (*ppv)
{
((LPUNKNOWN) *ppv)->AddRef();
hr = S_OK;
}
return hr;
}
// **************************************************************************
// Function Name: AddRef
// Purpose: COM reference counting
// Description:
// Implements IUnknown::Addref by adding 1 to the object's reference count
ULONG CFactory::AddRef()
{
RETAILMSG(TRUE, (TEXT("Factory Reference is now %d\r\n"), m_cRef + 1));
return InterlockedIncrement(&m_cRef);
}
// **************************************************************************
// Function Name: Release
// Purpose: COM ref