Monitoring SMS message and replying programmatically on Windows Mobile

Download the source code

Here is an application that will monitor SMS message and if the message is coming from predefined numbers then reply that SMS with some predefined text.

There are two components in this sample. MailRuleClient and DatabaseManager. The Mail Rule Client is a COM component. The Database Manager manages the database. The database stores the numbers we have to monitor, a flag which represents the actions (delete, reply message) we have to take and the Message to reply with. For the database part EDB is used instead of CEDB. For the Mail Rule Client component I took most of the code from the MailRule sample of the Windows Mobile 6 SDK. You can find sample code in the folder drive:Program FilesWindows Mobile 6 SDKSamplesCommonCPPWin32MapiRule

To monitor SMS messages there are two methods. First method is to use one of the State and Notification Broker functions like RegistryNotifyApp, RegistryNotifyWindow, etc… Upon receiving SMS message, the system will execute the application specified or send a message to specified window. If you are using RegistryNotifyApp API, our application will start with command line parameter /notify with the value name you specified in the third parameter of the API. We parse the command line and if /notify is found we read the new SMS message and reply to that.

A better approach is to use IMailRuleClient interface. This interface allows you to implement a mail rule that can process the incoming messages. There are two methods we have to implement. Initialize and ProcessMessage. A rule client is a regular COM component which is registered in the system. In addition to the registration we have to create an additional registry entry under

[HKEY_LOCAL_MACHINESoftwareMicrosoftInboxSvcRules] = dword: 1 There is only one < TransportName> currently supported, “SMS”.

If we are our component is the first registered mail rule client, then default messaging application (tmail.exe) will launch our DLL and call the Initialize method of the IMailRuleClient. Whenever and SMS comes in, the ProcessMessage method will be called with appropriate parameters. The return value of this method determines whether system process the SMS normally.

The syntax of these methods is:

HRESULT Initialize(IMsgStore* pMsgStore, MRCACCESS* pmaDesired);
HRESULT ProcessMessage(IMsgStore* pMsgStore,ULONG cbMsg,LPENTRYID lpMsg, ULONG cbDestFolder, LPENTRYID lpDestFolder, ULONG* pulEventType, MRCHANDLED* pHandled);

The first parameter of the Initialize method is a pointer to the IMsgStore. This represents the message store of the incoming messages. The second parameter is pointer to the MRCACCESS enum which we have to fill with our desired access. Possible values can be

MRC_ACCESS_NONE
MRC_ACCESS_READ_ONLY
MRC_ACCESS_WRITE

The first parameter of the ProcessMessage method is a pointer to IMsgStore representing the message store. Second parameter is the length of the third parameter lpMsg which pointer to the ENTRYID structure which represents the message. The ENTRYID contains an identifier of an MAPI object. This is a unique identifier used by the message store and address book providers. The fourth parameter is the length of the fifth parameter which is again a pointer to the ENTRYID structure which represents the folder that contains the message. We have to fill the sixth parameter which is a ULONG pointer with appropriate bit flags. Possible flags are:

fnevObjectCreated
fnevObjectDeleted
fnevObjectModified
fnevObjectMoved
fnevObjectCopied

These flags are self explanatory and do not need any explanation. The seventh parameter is a pointer to the MRCHANDLED which we have to fill with appropriate values. Possible values are:

MRC_NOT_HANDLED
MRC_HANDLED_CONTINUE
MRC_HANDLED_DONTCONTINUE

Again these are self explanatory and explanation is not needed.

About the implementation part, when our ProcessMessage method is called first we take the IMessage pointer using the OpenEntry method of the IMsgStore that is passed in.

hr = pMsgStore->OpenEntry(cbMsg,lpMsg,NULL,0,NULL,(LPUNKNOWN *)&pMsg);

Then we take the subject and sender address of the message using the code:


SizedSPropTagArray(1, sptaSubject) = {1,PR_SUBJECT};
SizedSPropTagArray(1, sptaEmail) = {1,PR_SENDER_EMAIL_ADDRESS};

hr = pMsg->GetProps((SPropTagArray*)&sptaSubject,MAPI_UNICODE,&cValues,&pspvSubject);

if (FAILED(hr))
{
return hr;
}

hr = pMsg->GetProps((SPropTagArray *)&sptaEmail,MAPI_UNICODE,&cValues,&pspvEmail);

if (FAILED(hr))
{
return hr;
}

Then we open an EDB database and check whether the address is there in the database and if there we get the message to reply with. The database contains 3 fields

Number to monitor
Bit flags representing what action to be taken and
The message body used to reply.

The database part is handled by two classes: CSMSRespondDB and CSMSRespondRecord.

Both sample workspaces are compiled using Visual Studio 2008 using Windows Mobile 6 SDK.

The handling of EDB database deserves another article and I am working on that. I will update this blog when it is finished.

Hope this gives you a simple introduction to the Message Rule clients.

8 Comments

Add yours →

  1. cool article, but it lacks information about how to install this sample, and how to debug it then. Everyone is just a telepath…

  2. cool article, but it lacks information about how to install this sample, and how to debug it then. Everyone is just a telepath…

  3. cool article, but it lacks information about how to install this sample, and how to debug it then. Everyone is just a telepath…

  4. cool article, but it lacks information about how to install this sample, and how to debug it then. Everyone is just a telepath…

Leave a Reply