Пример #1
0
static INT_PTR icqRecvFile(WPARAM wParam, LPARAM lParam)
{
    DBEVENTINFO dbei;
    CCSDATA *ccs = (CCSDATA *)lParam;
    PROTORECVEVENT *pre = (PROTORECVEVENT *)ccs->lParam;
    char *szDesc, *szFile;

    T("[   ] recieve file\n");

    db_unset(ccs->hContact, "CList", "Hidden");

    szFile = pre->szMessage + sizeof(DWORD);
    szDesc = szFile + mir_strlen(szFile) + 1;

    ZeroMemory(&dbei, sizeof(dbei));
    dbei.cbSize = sizeof(dbei);
    dbei.szModule = protoName;
    dbei.timestamp = pre->timestamp;
    dbei.flags = pre->flags & (PREF_CREATEREAD ? DBEF_READ : 0);
    dbei.eventType = EVENTTYPE_FILE;
    dbei.cbBlob = sizeof(DWORD) + (DWORD)mir_strlen(szFile) + (DWORD)mir_strlen(szDesc) + 2;
    dbei.pBlob = (PBYTE)pre->szMessage;
    db_event_add(ccs->hContact, &dbei);

    return 0;
}
Пример #2
0
BOOL CJabberProto::AddDbPresenceEvent(MCONTACT hContact, BYTE btEventType)
{
	if (!hContact)
		return FALSE;

	switch (btEventType) {
	case JABBER_DB_EVENT_PRESENCE_SUBSCRIBE:
	case JABBER_DB_EVENT_PRESENCE_SUBSCRIBED:
	case JABBER_DB_EVENT_PRESENCE_UNSUBSCRIBE:
	case JABBER_DB_EVENT_PRESENCE_UNSUBSCRIBED:
		if (!m_options.LogPresence)
			return FALSE;
		break;

	case JABBER_DB_EVENT_PRESENCE_ERROR:
		if (!m_options.LogPresenceErrors)
			return FALSE;
		break;
	}

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.pBlob = &btEventType;
	dbei.cbBlob = sizeof(btEventType);
	dbei.eventType = JABBER_DB_EVENT_TYPE_PRESENCE;
	dbei.flags = DBEF_READ;
	dbei.timestamp = time(NULL);
	dbei.szModule = m_szModuleName;
	db_event_add(hContact, &dbei);

	return TRUE;
}
Пример #3
0
// process ACK messages for the send later job list. Called from the proto ack
// handler when it does not find a match in the normal send queue
//
// Add the message to the database and mark it as successful. The job will be
// removed later by the job list processing code.
//
HANDLE CSendLater::processAck(const ACKDATA *ack)
{
	if (m_sendLaterJobList.getCount() == 0 || !m_fAvail)
		return 0;

	for (int i=0; i < m_sendLaterJobList.getCount(); i++) {
		CSendLaterJob *p = m_sendLaterJobList[i];
		if (p->hProcess == ack->hProcess && p->hTargetContact == ack->hContact && !(p->fSuccess || p->fFailed)) {
			if (!p->fSuccess) {
				DBEVENTINFO dbei = { sizeof(dbei) };
				dbei.eventType = EVENTTYPE_MESSAGE;
				dbei.flags = DBEF_SENT;
				dbei.szModule = GetContactProto((p->hContact));
				dbei.timestamp = time(NULL);
				dbei.cbBlob = lstrlenA(p->sendBuffer) + 1;
				dbei.flags |= DBEF_UTF;
				dbei.pBlob = (PBYTE)(p->sendBuffer);
				db_event_add(p->hContact, &dbei);
				
				p->cleanDB();
			}
			p->fSuccess = true;					// mark as successful, job list processing code will remove it later
			p->hProcess = (HANDLE)-1;
			p->bCode = '-';
			qMgrUpdate();
			return 0;
		}
	}
	return 0;
}
Пример #4
0
/**
* Protocols àcknowledgement
*/
int ProtoAck(WPARAM wparam,LPARAM lparam)
{
	ACKDATA *pAck = (ACKDATA *)lparam;
	if (pAck->type != ACKTYPE_MESSAGE || pAck->result != ACKRESULT_SUCCESS)
		return 0;

	MESSAGE_PROC* p = arMessageProcs.find((MESSAGE_PROC*)&pAck->hProcess);
	if (p == NULL)
		return 0;

	if (iSendAndHistory > 0){
		time_t ltime;
		time(&ltime);

		DBEVENTINFO dbei = { sizeof(dbei) };
		dbei.szModule = "yaRelay";
		dbei.timestamp = ltime;
		dbei.flags = DBEF_SENT | DBEF_UTF;
		dbei.eventType = EVENTTYPE_MESSAGE;
		dbei.cbBlob = (DWORD)strlen(p->msgText) + 1;
		dbei.pBlob = (PBYTE)p->msgText;
		db_event_add(hForwardTo, &dbei);
	}

	mir_free(p->msgText);
	arMessageProcs.remove(p);
	mir_free(p);
	return 0;
}
Пример #5
0
void MarkUnread(MCONTACT hContact)
{
	// We're not actually marking anything. We just pushing saved events to the database from a temporary location
	DBVARIANT _dbv = {0};
	PBYTE pos;
	
	if (hContact == NULL)
		return;
	
	if (db_get(hContact, PLUGIN_NAME, "LastMsgEvents", &_dbv) == 0) {
		pos = _dbv.pbVal;
		while (pos - _dbv.pbVal < _dbv.cpbVal) {
			DBEVENTINFO _dbei;
			ZeroMemory(&_dbei, sizeof(_dbei));
			_dbei.cbSize = sizeof(_dbei);

			memcpy(&_dbei.eventType, pos, sizeof(WORD)); pos += sizeof(WORD);
			memcpy(&_dbei.flags, pos, sizeof(DWORD)); pos += sizeof(DWORD);
			memcpy(&_dbei.timestamp, pos, sizeof(DWORD)); pos += sizeof(DWORD);

			_dbei.szModule = (char*)malloc(strlen((const char*)pos)+1);
			strcpy(_dbei.szModule, (const char*)pos);
			pos += strlen((const char*)pos)+1;

			memcpy(&_dbei.cbBlob, pos, sizeof(DWORD)); pos += sizeof(DWORD);
			_dbei.pBlob = (PBYTE)malloc(_dbei.cbBlob);
			memcpy(_dbei.pBlob, pos, _dbei.cbBlob);
			pos += _dbei.cbBlob;

			db_event_add(hContact,&_dbei);
		}
		db_free(&_dbv);
		db_unset(hContact, PLUGIN_NAME, "LastMsgEvents");
	}
}
Пример #6
0
void EventList::MargeMessages(const std::vector<IImport::ExternalMessage>& messages)
{
	ImportMessages(messages);
	std::list<EventTempIndex> tempList;
	GetTempList(tempList, true, false, hContact);

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = GetContactProto(hContact);

	CallService(MS_DB_SETSAFETYMODE, FALSE, 0);
	for (std::list<EventTempIndex>::iterator it = tempList.begin(); it != tempList.end(); ++it) {
		if (it->isExternal) {
			IImport::ExternalMessage& msg = importedMessages[it->exIdx];
			dbei.flags |= DBEF_READ;
			dbei.timestamp = msg.timestamp;
			// For now I do not convert event data from string to blob, and event type must be message to handle it properly
			dbei.eventType = EVENTTYPE_MESSAGE;
			UINT cp = dbei.flags & DBEF_UTF ? CP_UTF8 : CP_ACP;
			dbei.cbBlob = WideCharToMultiByte(cp, 0, msg.message.c_str(), (int)msg.message.length() + 1, NULL, 0, NULL, NULL);
			char* buf = new char[dbei.cbBlob];
			dbei.cbBlob = WideCharToMultiByte(cp, 0, msg.message.c_str(), (int)msg.message.length() + 1, buf, dbei.cbBlob, NULL, NULL);
			dbei.pBlob = (PBYTE)buf;
			db_event_add(hContact, &dbei);
			delete [] buf;
		}
	}

	CallService(MS_DB_SETSAFETYMODE, TRUE, 0);
	std::vector<IImport::ExternalMessage> emessages;
	ImportMessages(emessages);
}
Пример #7
0
void CJabberProto::DBAddAuthRequest(const TCHAR *jid, const TCHAR *nick)
{
	MCONTACT hContact = DBCreateContact(jid, nick, TRUE, TRUE);
	delSetting(hContact, "Hidden");

	char* szJid = mir_utf8encodeT(jid);
	char* szNick = mir_utf8encodeT(nick);

	//blob is: uin(DWORD), hContact(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ)
	//blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ)
	DBEVENTINFO dbei = { sizeof(DBEVENTINFO) };
	dbei.szModule = m_szModuleName;
	dbei.timestamp = (DWORD)time(NULL);
	dbei.flags = DBEF_UTF;
	dbei.eventType = EVENTTYPE_AUTHREQUEST;
	dbei.cbBlob = (DWORD)(sizeof(DWORD)*2 + strlen(szNick) + strlen(szJid) + 5);
	PBYTE pCurBlob = dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
	*((PDWORD)pCurBlob) = 0; pCurBlob += sizeof(DWORD);
	*((PDWORD)pCurBlob) = (DWORD)hContact; pCurBlob += sizeof(DWORD);
	strcpy((char*)pCurBlob, szNick); pCurBlob += strlen(szNick)+1;
	*pCurBlob = '\0'; pCurBlob++;		//firstName
	*pCurBlob = '\0'; pCurBlob++;		//lastName
	strcpy((char*)pCurBlob, szJid); pCurBlob += strlen(szJid)+1;
	*pCurBlob = '\0';					//reason

	db_event_add(NULL, &dbei);
	debugLogA("Setup DBAUTHREQUEST with nick='%s' jid='%s'", szNick, szJid);

	mir_free(szJid);
	mir_free(szNick);
}
Пример #8
0
void msgQueue_processack(MCONTACT hContact, int id, BOOL success, const char *szErr)
{
    TMsgQueue *p = msgQueue_find(hContact, id);
    if (p == NULL)
        return;

    if (!success) {
        MessageFailureProcess(p, szErr);
        return;
    }

    DBEVENTINFO dbei = { sizeof(dbei) };
    dbei.eventType = EVENTTYPE_MESSAGE;
    dbei.flags = DBEF_SENT | DBEF_UTF | (p->flags & PREF_RTL ? DBEF_RTL : 0);
    dbei.szModule = GetContactProto(hContact);
    dbei.timestamp = time(0);
    dbei.cbBlob = (DWORD)(mir_strlen(p->szMsg) + 1);
    dbei.pBlob = (PBYTE)p->szMsg;

    MessageWindowEvent evt = { sizeof(evt), id, hContact, &dbei };
    NotifyEventHooks(hHookWinWrite, 0, (LPARAM)&evt);

    p->szMsg = (char*)dbei.pBlob;

    db_event_add(hContact, &dbei);

    mir_free(p->szMsg);
    mir_free(p);
}
Пример #9
0
void CJabberProto::OnIqResultGetCollection(HXML iqNode, CJabberIqInfo*)
{
	if ( mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result")))
		return;

	HXML chatNode = xmlGetChild(iqNode, "chat");
	if (!chatNode || mir_tstrcmp( xmlGetAttrValue(chatNode, _T("xmlns")), JABBER_FEAT_ARCHIVE))
		return;

	const TCHAR* start = xmlGetAttrValue(chatNode, _T("start"));
	const TCHAR* with  = xmlGetAttrValue(chatNode, _T("with"));
	if (!start || !with)
		return;

	MCONTACT hContact = HContactFromJID(with);
	time_t tmStart = str2time(start);
	if (hContact == 0 || tmStart == 0)
		return;

	_tzset();

	for (int nodeIdx = 0; ; nodeIdx++) {
		HXML itemNode = xmlGetChild(chatNode, nodeIdx);
		if (!itemNode)
			break;

		int from;
		const TCHAR *itemName = xmlGetName(itemNode);
		if (!mir_tstrcmp(itemName, _T("to")))
			from = DBEF_SENT;
		else if (!mir_tstrcmp(itemName, _T("from")))
			from = 0;
		else
			continue;

		HXML body = xmlGetChild(itemNode, "body");
		if (!body)
			continue;

		const TCHAR *tszBody = xmlGetText(body);
		const TCHAR *tszSecs = xmlGetAttrValue(itemNode, _T("secs"));
		if (!tszBody || !tszSecs)
			continue;

		ptrA szEventText( mir_utf8encodeT(tszBody));

		DBEVENTINFO dbei = { sizeof(DBEVENTINFO) };
		dbei.eventType = EVENTTYPE_MESSAGE;
		dbei.szModule = m_szModuleName;
		dbei.cbBlob = (DWORD)strlen(szEventText);
		dbei.flags = DBEF_READ + DBEF_UTF + from;
		dbei.pBlob = (PBYTE)(char*)szEventText;
		dbei.timestamp = tmStart + _ttol(tszSecs) - timezone;
		if (!IsDuplicateEvent(hContact, dbei))
			db_event_add(hContact, &dbei);
	}
}
Пример #10
0
MEVENT CToxProto::AddEventToDb(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, PBYTE pBlob, size_t cbBlob)
{
	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = this->m_szModuleName;
	dbei.timestamp = timestamp;
	dbei.eventType = type;
	dbei.cbBlob = (DWORD)cbBlob;
	dbei.pBlob = pBlob;
	dbei.flags = flags;
	return db_event_add(hContact, &dbei);
}
Пример #11
0
void HistoryLog(HANDLE hContact, char *data, int event_type, int flags)
{
	DBEVENTINFO Event = { sizeof(Event) };
	Event.szModule = pluginName;
	Event.eventType = event_type;
	Event.flags = flags | DBEF_UTF;
	Event.timestamp = (DWORD)time(NULL);
	Event.cbBlob = (DWORD)strlen(data)+1;
	Event.pBlob = (PBYTE)_strdup(data);
	db_event_add(hContact, &Event);
}
Пример #12
0
void CSend::DB_EventAdd(WORD EventType)
{
	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = m_pszProto;
	dbei.eventType = EventType;
	dbei.flags = DBEF_SENT;
	dbei.timestamp = time(NULL);
	dbei.flags |= DBEF_UTF;
	dbei.cbBlob = m_cbEventMsg;
	dbei.pBlob = (PBYTE)m_szEventMsg;
	db_event_add(m_hContact, &dbei);
}
Пример #13
0
void MirandaUtils::addMessageToDB(HANDLE hContact, int mirandaSendModeFlag, char* msgBuffer, std::size_t bufSize, char* targetHandleSzProto)
{
	DBEVENTINFO dbei = {0};
	dbei.cbSize = sizeof(dbei);
	dbei.eventType = EVENTTYPE_MESSAGE;
	dbei.flags = DBEF_SENT | ((mirandaSendModeFlag&PREF_UTF)==PREF_UTF ? DBEF_UTF : 0);
	dbei.szModule = targetHandleSzProto;
	dbei.timestamp = (DWORD)time(NULL);
	dbei.cbBlob = (DWORD)bufSize;
	dbei.pBlob = (PBYTE)msgBuffer;
	db_event_add(hContact, &dbei);
}
Пример #14
0
MEVENT CSteamProto::AddDBEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob)
{
	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = m_szModuleName;
	dbei.timestamp = timestamp;
	dbei.eventType = type;
	dbei.cbBlob = cbBlob;
	dbei.pBlob = pBlob;
	dbei.flags = flags;

	return db_event_add(hContact, &dbei);
}
Пример #15
0
int CMraProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
{
    DBEVENTINFO dbei = { sizeof(dbei) };
    dbei.szModule = m_szModuleName;
    dbei.timestamp = pre->timestamp;
    dbei.flags = (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0;
    dbei.eventType = EVENTTYPE_CONTACTS;
    dbei.cbBlob = pre->lParam;
    dbei.pBlob = (PBYTE)pre->szMessage;
    db_event_add(hContact, &dbei);
    return 0;
}
Пример #16
0
MEVENT CDropbox::AddEventToDb(MCONTACT hContact, WORD type, DWORD flags, DWORD cbBlob, PBYTE pBlob)
{
	DBEVENTINFO dbei;
	dbei.cbSize = sizeof(dbei);
	dbei.szModule = MODULE;
	dbei.timestamp = time(NULL);
	dbei.eventType = type;
	dbei.cbBlob = cbBlob;
	dbei.pBlob = pBlob;
	dbei.flags = flags;
	return db_event_add(hContact, &dbei);
}
Пример #17
0
void Nudge_ShowStatus(CNudgeElement *n, MCONTACT hContact, DWORD timestamp)
{
	T2Utf buff(n->recText);

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = MODULENAME;
	dbei.eventType = 1;
	dbei.flags = DBEF_UTF;
	dbei.timestamp = timestamp;
	dbei.cbBlob = (DWORD)mir_strlen(buff) + 1;
	dbei.pBlob = (PBYTE)buff;
	db_event_add(hContact, &dbei);
}
Пример #18
0
static MEVENT AddCListNotification(MCONTACT hContact, LPCSTR acc, POPUPDATAT *data, LPCTSTR url)
{
	T2Utf szUrl(url), szText(data->lptzText);

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = (LPSTR)acc;
	dbei.timestamp = time(NULL);
	dbei.flags = DBEF_UTF;
	dbei.eventType = EVENTTYPE_MESSAGE;

	char szEventText[4096];
	dbei.cbBlob = mir_snprintf(szEventText, _countof(szEventText), "%s\r\n%s", szUrl, szText);
	dbei.pBlob = (PBYTE)szEventText;
	return db_event_add(hContact, &dbei);
}
Пример #19
0
INT_PTR CDropbox::ProtoReceiveMessage(WPARAM, LPARAM lParam)
{
	CCSDATA *pccsd = (CCSDATA*)lParam;

	char *message = (char*)pccsd->lParam;

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.flags = DBEF_UTF;
	dbei.szModule = MODULE;
	dbei.timestamp = time(NULL);
	dbei.eventType = EVENTTYPE_MESSAGE;
	dbei.cbBlob = (int)mir_strlen(message);
	dbei.pBlob = (PBYTE)mir_strdup(message);
	db_event_add(pccsd->hContact, &dbei);

	return 0;
}
Пример #20
0
void log_to_history(const IQuotesProvider* pProvider,
	MCONTACT hContact,
	time_t nTime,
	const tstring& rsFormat)
{
	tstring s = format_rate(pProvider, hContact, rsFormat);
	T2Utf psz(s.c_str());

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = QUOTES_PROTOCOL_NAME;
	dbei.timestamp = static_cast<DWORD>(nTime);
	dbei.flags = DBEF_READ | DBEF_UTF;
	dbei.eventType = EVENTTYPE_MESSAGE;
	dbei.cbBlob = (int)::mir_strlen(psz) + 1;
	dbei.pBlob = (PBYTE)(char*)psz;
	db_event_add(hContact, &dbei);
}
Пример #21
0
INT_PTR CDropbox::ProtoReceiveMessage(void *obj, WPARAM, LPARAM lParam)
{
	CDropbox *instance = (CDropbox*)obj;

	CCSDATA *pccsd = (CCSDATA*)lParam;

	char *message = (char*)pccsd->lParam;

	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.szModule = MODULE;
	dbei.timestamp = time(NULL);
	dbei.eventType = EVENTTYPE_MESSAGE;
	dbei.cbBlob = strlen(message);
	dbei.pBlob = (PBYTE)message;
	db_event_add(pccsd->hContact, &dbei);

	return 0;
}
Пример #22
0
int LogToSystemHistory(char *message, char *origmessage)
{
	char *msg = (char*)malloc(MAX_BUFFER_LENGTH);
	time_t tm;
	DBEVENTINFO dbei;
	dbei.cbSize = sizeof(DBEVENTINFO);
	dbei.timestamp = time(&tm);
	dbei.szModule = PLUGIN_NAME;
	if (origmessage)
		mir_snprintf(msg, MAX_BUFFER_LENGTH, "%s: %s%s %s: %s", PLUGIN_NAME, message, DOT(message), Translate("Their message was"), origmessage);
	else 
		mir_snprintf(msg, MAX_BUFFER_LENGTH, "%s: %s%s", PLUGIN_NAME, message, DOT(message));
	dbei.pBlob = (PBYTE)msg;
	dbei.cbBlob = (DWORD)strlen(msg)+1;
	dbei.eventType = EVENTTYPE_MESSAGE;
	dbei.flags = DBEF_READ;
	db_event_add(NULL, &dbei);
	return 0;
}
Пример #23
0
static INT_PTR icqRecvMessage(WPARAM wParam, LPARAM lParam)
{
    DBEVENTINFO dbei;
    CCSDATA *ccs = (CCSDATA*)lParam;
    PROTORECVEVENT *pre = (PROTORECVEVENT*)ccs->lParam;

    T("[   ] recieve message\n");

    db_unset(ccs->hContact, "CList", "Hidden");
    ZeroMemory(&dbei, sizeof(dbei));
    dbei.cbSize = sizeof(dbei);
    dbei.szModule = protoName;
    dbei.timestamp = pre->timestamp;
    dbei.flags = pre->flags & (PREF_CREATEREAD ? DBEF_READ : 0);
    dbei.eventType = EVENTTYPE_MESSAGE;
    dbei.cbBlob = (DWORD)mir_tstrlen(pre->szMessage) + 1;
    dbei.pBlob = (PBYTE)pre->szMessage;
    db_event_add(ccs->hContact, &dbei);
    return 0;
}
Пример #24
0
void LogSMsgToDB(STATUSMSGINFO *smi, const wchar_t *tmplt)
{
	ptrW str(GetStr(smi, tmplt));
	T2Utf blob(str);

	DBEVENTINFO dbei = {};
	dbei.cbBlob = (DWORD)mir_strlen(blob) + 1;
	dbei.pBlob = (PBYTE)blob;
	dbei.eventType = EVENTTYPE_STATUSCHANGE;
	dbei.flags = DBEF_READ | DBEF_UTF;

	dbei.timestamp = (DWORD)time(0);
	dbei.szModule = MODULE;
	MEVENT hDBEvent = db_event_add(smi->hContact, &dbei);

	if (opt.SMsgLogToDB_WinOpen && opt.SMsgLogToDB_Remove) {
		DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT));
		dbevent->hContact = smi->hContact;
		dbevent->hDBEvent = hDBEvent;
		eventListSMsg.insert(dbevent);
	}
}
Пример #25
0
int MsgAck(WPARAM, LPARAM lParam) 
{ 
	ACKDATA *ack=(ACKDATA*)lParam; 

	if (ack && ack->cbSize == sizeof(ACKDATA) && ack->type == ACKTYPE_MESSAGE) {
		if (ack->hProcess == (HANDLE)WindowList_Find(hWindowList,ack->hContact)) { 
			if (db_get_b(NULL, modname, "ShowDeliveryMessages", 1))
				CreateMessageAcknowlegedWindow(ack->hContact,ack->result == ACKRESULT_SUCCESS);
			if (ack->result == ACKRESULT_SUCCESS) {
				// wrtie it to the DB
				DBEVENTINFO dbei = { 0 };
				DBVARIANT dbv;
				int reuse = db_get_b(ack->hContact,modname, "Reuse", 0);
				if (!db_get_ts(ack->hContact, modname, "PounceMsg", &dbv) && (dbv.ptszVal[0] != '\0')) {
					T2Utf pszUtf(dbv.ptszVal);
					dbei.cbSize = sizeof(dbei);
					dbei.eventType = EVENTTYPE_MESSAGE;
					dbei.flags = DBEF_UTF | DBEF_SENT;
					dbei.szModule = (char*)ack->szModule;
					dbei.timestamp = time(NULL);
					dbei.cbBlob = (int)mir_strlen(pszUtf) + 1;
					dbei.pBlob = (PBYTE)(char*)pszUtf;
					db_event_add(ack->hContact, &dbei);
				}
				// check to reuse
				if (reuse > 1)
					db_set_b(ack->hContact, modname, "Reuse", (BYTE)(reuse-1));
				else {
					db_set_b(ack->hContact,modname, "Reuse", 0);
					db_set_ws(ack->hContact, modname, "PounceMsg", _T(""));
				}
			}
			WindowList_Remove(hWindowList,(HWND)ack->hProcess);
		}
	} 
	return 0; 
} 
Пример #26
0
// MsnRecvContacts - creates a database event from the contacts received
int CMsnProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
{
	PROTOSEARCHRESULT **isrList = (PROTOSEARCHRESULT**)pre->szMessage;
	DBEVENTINFO dbei = { sizeof(dbei) };
	BYTE *pCurBlob;
	int i;

	for (i = 0; i < pre->lParam; i++)
		dbei.cbBlob += int(mir_tstrlen(isrList[i]->nick.t) + 2 + mir_tstrlen(isrList[i]->id.t));
	dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob);
	for (i = 0, pCurBlob = dbei.pBlob; i < pre->lParam; i++) {
		mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->nick.t));
		pCurBlob += mir_strlen((char*)pCurBlob) + 1;
		mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->id.t));
		pCurBlob += mir_strlen((char*)pCurBlob) + 1;
	}

	dbei.szModule = m_szModuleName;
	dbei.timestamp = pre->timestamp;
	dbei.flags = (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0;
	dbei.eventType = EVENTTYPE_CONTACTS;
	db_event_add(hContact, &dbei);
	return 0;
}
Пример #27
0
// This function handles the ACK received from that hooked.
int handleAckSMS(WPARAM wParam, LPARAM lParam)
{
	if (!lParam)
		return 0;
	if (((ACKDATA*)lParam)->type != ICQACKTYPE_SMS)
		return 0;

	char szPhone[MAX_PHONE_LEN] = { 0 };
	TCHAR tszPhone[MAX_PHONE_LEN] = { 0 };
	LPSTR lpszXML = (LPSTR)((ACKDATA*)lParam)->lParam, lpszData, lpszPhone;
	size_t dwXMLSize = 0, dwDataSize, dwPhoneSize;
	ACKDATA *ack = ((ACKDATA*)lParam);

	if (lpszXML)
		dwXMLSize = mir_strlen(lpszXML);

	if (GetXMLFieldEx(lpszXML, dwXMLSize, &lpszData, &dwDataSize, "sms_message", "text", NULL)) {
		if (GetXMLFieldEx(lpszXML, dwXMLSize, &lpszPhone, &dwPhoneSize, "sms_message", "sender", NULL)) {
			LPSTR lpszMessageUTF;
			size_t dwBuffLen, dwMessageXMLEncodedSize, dwMessageXMLDecodedSize;
			DBEVENTINFO dbei = { sizeof(dbei) };

			dwBuffLen = (dwDataSize + MAX_PATH);
			dbei.pBlob = (LPBYTE)MEMALLOC((dwBuffLen + dwPhoneSize));
			LPWSTR lpwszMessageXMLEncoded = (LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR)));
			LPWSTR lpwszMessageXMLDecoded = (LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR)));
			if (dbei.pBlob && lpwszMessageXMLEncoded && lpwszMessageXMLDecoded) {
				dwMessageXMLEncodedSize = MultiByteToWideChar(CP_UTF8, 0, lpszData, (int)dwDataSize, lpwszMessageXMLEncoded, (int)dwBuffLen);
				DecodeXML(lpwszMessageXMLEncoded, dwMessageXMLEncodedSize, lpwszMessageXMLDecoded, dwBuffLen, &dwMessageXMLDecodedSize);
				lpszMessageUTF = (LPSTR)lpwszMessageXMLEncoded;
				WideCharToMultiByte(CP_UTF8, 0, lpwszMessageXMLDecoded, (int)dwMessageXMLDecodedSize, lpszMessageUTF, (int)dwBuffLen, NULL, NULL);

				dwPhoneSize = CopyNumberA(szPhone, lpszPhone, dwPhoneSize);
				dwPhoneSize = MultiByteToWideChar(CP_UTF8, 0, szPhone, (int)dwPhoneSize, tszPhone, MAX_PHONE_LEN);
				MCONTACT hContact = HContactFromPhone(tszPhone, dwPhoneSize);

				dbei.szModule = GetModuleName(hContact);
				dbei.timestamp = time(NULL);
				dbei.flags = DBEF_UTF;
				dbei.eventType = ICQEVENTTYPE_SMS;
				dbei.cbBlob = (mir_snprintf((LPSTR)dbei.pBlob, ((dwBuffLen + dwPhoneSize)), "SMS From: +%s\r\n%s", szPhone, lpszMessageUTF) + sizeof(DWORD));
				//dbei.pBlob=(LPBYTE)lpszBuff;
				(*((DWORD*)(dbei.pBlob + (dbei.cbBlob - sizeof(DWORD))))) = 0;
				MEVENT hResult = db_event_add(hContact, &dbei);
				if (hContact == NULL) {
					if (RecvSMSWindowAdd(NULL, ICQEVENTTYPE_SMS, tszPhone, dwPhoneSize, (LPSTR)dbei.pBlob, dbei.cbBlob)) {
						db_event_markRead(hContact, hResult);
						SkinPlaySound("RecvSMSMsg");
					}
				}
			}
			MEMFREE(lpwszMessageXMLDecoded);
			MEMFREE(lpwszMessageXMLEncoded);
			MEMFREE(dbei.pBlob);
		}
	}
	else
		if (GetXMLFieldEx(lpszXML, dwXMLSize, &lpszData, &dwDataSize, "sms_delivery_receipt", "delivered", NULL)) {
			if (GetXMLFieldEx(lpszXML, dwXMLSize, &lpszPhone, &dwPhoneSize, "sms_delivery_receipt", "destination", NULL)) {
				dwPhoneSize = CopyNumberA(szPhone, lpszPhone, dwPhoneSize);
				dwPhoneSize = MultiByteToWideChar(CP_UTF8, 0, szPhone, (int)dwPhoneSize, tszPhone, MAX_PHONE_LEN);
				MCONTACT hContact = HContactFromPhone(tszPhone, dwPhoneSize);

				DBEVENTINFO dbei = { 0 };
				dbei.cbSize = sizeof(dbei);
				dbei.szModule = GetModuleName(hContact);
				dbei.timestamp = time(NULL);
				dbei.flags = DBEF_UTF;
				dbei.eventType = ICQEVENTTYPE_SMSCONFIRMATION;
				if (CompareStringA(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, lpszData, (int)dwDataSize, "yes", 3) == CSTR_EQUAL) {
					dbei.cbBlob = (MAX_PHONE_LEN + MAX_PATH);
					dbei.pBlob = (PBYTE)MEMALLOC(dbei.cbBlob);
					if (dbei.pBlob) dbei.cbBlob = (mir_snprintf((LPSTR)dbei.pBlob, dbei.cbBlob, "SMS Confirmation From: +%s\r\nSMS was sent succesfully", szPhone) + 4);
				}
				else {
					if (GetXMLFieldEx(lpszXML, dwXMLSize, &lpszData, &dwDataSize, "sms_delivery_receipt", "error", "params", "param", NULL) == FALSE) {
						lpszData = "";
						dwDataSize = 0;
					}
					dbei.cbBlob = (int)(MAX_PHONE_LEN + MAX_PATH + dwDataSize);
					dbei.pBlob = (PBYTE)MEMALLOC(dbei.cbBlob);
					if (dbei.pBlob) {
						dbei.cbBlob = mir_snprintf((LPSTR)dbei.pBlob, dbei.cbBlob, "SMS Confirmation From: +%s\r\nSMS was not sent succesfully: ", szPhone);
						memcpy((dbei.pBlob + dbei.cbBlob), lpszData, dwDataSize);
						dbei.cbBlob += (int)(dwDataSize + sizeof(DWORD));
						(*((DWORD*)(dbei.pBlob + (dbei.cbBlob - sizeof(DWORD))))) = 0;
					}
				}

				if (dbei.pBlob) {
					if (hContact)
						db_event_add(hContact, &dbei);
					else
						RecvSMSWindowAdd(NULL, ICQEVENTTYPE_SMSCONFIRMATION, tszPhone, dwPhoneSize, (LPSTR)dbei.pBlob, dbei.cbBlob);

					MEMFREE(dbei.pBlob);
				}
			}
		}
		else
			if ((ack->result == ACKRESULT_FAILED) || GetXMLFieldEx(lpszXML, dwXMLSize, &lpszData, &dwDataSize, "sms_response", "deliverable", NULL)) {
				HWND hWndDlg = SendSMSWindowHwndByHProcessGet(ack->hProcess);
				if (hWndDlg) {
					char szNetwork[MAX_PATH];

					KillTimer(hWndDlg, wParam);
					GetXMLFieldExBuff(lpszXML, dwXMLSize, szNetwork, sizeof(szNetwork), NULL, "sms_response", "network", NULL);

					if (ack->result == ACKRESULT_FAILED || CompareStringA(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, lpszData, (int)dwDataSize, "no", 2) == CSTR_EQUAL) {
						char szBuff[1024];
						TCHAR tszErrorMessage[1028];
						LPSTR lpszErrorDescription;

						if (SendSMSWindowMultipleGet(hWndDlg)) {
							TVITEM tvi;
							tvi.mask = TVIF_TEXT;
							tvi.hItem = SendSMSWindowHItemSendGet(hWndDlg);
							tvi.pszText = tszPhone;
							tvi.cchTextMax = _countof(tszPhone);
							TreeView_GetItem(GetDlgItem(hWndDlg, IDC_NUMBERSLIST), &tvi);
						}
						else GetDlgItemText(hWndDlg, IDC_ADDRESS, tszPhone, _countof(szPhone));

						if (ack->result == ACKRESULT_FAILED)
							lpszErrorDescription = lpszXML;
						else {
							lpszErrorDescription = szBuff;
							GetXMLFieldExBuff(lpszXML, dwXMLSize, szBuff, sizeof(szBuff), NULL, "sms_response", "error", "params", "param", NULL);
						}

						mir_sntprintf(tszErrorMessage, TranslateT("SMS message didn't send by %S to %s because: %S"), szNetwork, tszPhone, lpszErrorDescription);
						ShowWindow(hWndDlg, SW_SHOWNORMAL);
						EnableWindow(hWndDlg, FALSE);
						HWND hwndTimeOut = CreateDialog(ssSMSSettings.hInstance, MAKEINTRESOURCE(IDD_SENDSMSTIMEDOUT), hWndDlg, SMSTimedOutDlgProc);
						SetDlgItemText(hwndTimeOut, IDC_STATUS, tszErrorMessage);
					}
					else {
						SendSMSWindowDBAdd(hWndDlg);
						if (SendSMSWindowMultipleGet(hWndDlg)) {
							if (SendSMSWindowNextHItemGet(hWndDlg, SendSMSWindowHItemSendGet(hWndDlg))) {
								SendSMSWindowAsSentSet(hWndDlg);
								SendSMSWindowHItemSendSet(hWndDlg, SendSMSWindowNextHItemGet(hWndDlg, SendSMSWindowHItemSendGet(hWndDlg)));
								SendSMSWindowNext(hWndDlg);
							}
							else SendSMSWindowRemove(hWndDlg);
						}
						else {
							if (CompareStringA(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, lpszData, (int)dwDataSize, "yes", 3) == CSTR_EQUAL ||
								CompareStringA(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, lpszData, (int)dwDataSize, "smtp", 4) == CSTR_EQUAL) {
								char szSource[MAX_PATH], szMessageID[MAX_PATH];

								if (DB_SMS_GetByte(NULL, "ShowACK", SMS_DEFAULT_SHOWACK)) {
									HWND hwndAccepted = CreateDialog(ssSMSSettings.hInstance, MAKEINTRESOURCE(IDD_SENDSMSACCEPT), hWndDlg, SMSAcceptedDlgProc);
									if (CompareStringA(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), NORM_IGNORECASE, lpszData, (int)dwDataSize, "yes", 3) == CSTR_EQUAL) {
										GetXMLFieldExBuff(lpszXML, dwXMLSize, szSource, sizeof(szSource), NULL, "sms_response", "source", NULL);
										GetXMLFieldExBuff(lpszXML, dwXMLSize, szMessageID, sizeof(szMessageID), NULL, "sms_response", "message_id", NULL);
									}
									else {
										SetDlgItemText(hwndAccepted, IDC_ST_SOURCE, TranslateT("From:"));
										SetDlgItemText(hwndAccepted, IDC_ST_MESSAGEID, TranslateT("To:"));
										GetXMLFieldExBuff(lpszXML, dwXMLSize, szSource, sizeof(szSource), NULL, "sms_response", "from", NULL);
										GetXMLFieldExBuff(lpszXML, dwXMLSize, szMessageID, sizeof(szMessageID), NULL, "sms_response", "to", NULL);
									}
									SetDlgItemTextA(hwndAccepted, IDC_NETWORK, szNetwork);
									SetDlgItemTextA(hwndAccepted, IDC_SOURCE, szSource);
									SetDlgItemTextA(hwndAccepted, IDC_MESSAGEID, szMessageID);
								}
								else SendSMSWindowRemove(hWndDlg);
							}
							else SendSMSWindowRemove(hWndDlg);
						}
					}
				}
			}
	return 0;
}
Пример #28
0
INT addEvent(WPARAM hContact, LPARAM hDBEvent)
{
	BOOL fEnabled = db_get_b(NULL, protocolname, KEY_ENABLED, 1);
	if (!fEnabled || !hContact || !hDBEvent)
		return FALSE;	/// unspecifyed error

	char* pszProto = GetContactProto(hContact);
	int status = CallProtoService(pszProto, PS_GETSTATUS, 0, 0);
	if (status == ID_STATUS_ONLINE || status == ID_STATUS_FREECHAT || status == ID_STATUS_INVISIBLE)
		return FALSE;

	DBEVENTINFO dbei = {sizeof(dbei)};
	db_event_get(hDBEvent, &dbei); /// detect size of msg

	if ((dbei.eventType != EVENTTYPE_MESSAGE) || (dbei.flags == DBEF_READ))
		return FALSE; /// we need EVENTTYPE_MESSAGE event..
	else
	{	/// needed event has occured..
		DBVARIANT dbv;

		if (!dbei.cbBlob)	/// invalid size
			return FALSE;

		if (db_get_ts(hContact,"Protocol","p",&dbv))
			// Contact with no protocol ?!!
			return FALSE;
		else
			db_free(&dbv);

		if(db_get_b(hContact, "CList", "NotOnList", 0))
			return FALSE;

		if(db_get_b(hContact, protocolname, "TurnedOn", 0))
			return FALSE;

		if (!( dbei.flags & DBEF_SENT))
		{
			int timeBetween=time(NULL)-db_get_dw(hContact,protocolname,"LastReplyTS",0);
			if (timeBetween>interval || db_get_w(hContact,protocolname,"LastStatus",0)!=status)
			{
				char szStatus[6]={0};
				int msgLen=1;
				int isQun=db_get_b(hContact,pszProto,"IsQun",0);
				if (isQun)
					return FALSE;

				mir_snprintf(szStatus,_countof(szStatus),"%d",status);
				if (!db_get_ts(NULL,protocolname,szStatus,&dbv))
				{
					if (*dbv.ptszVal)
					{
						DBVARIANT dbvHead={0}, dbvNick={0};
						CMString ptszTemp;
						TCHAR *ptszTemp2;

						db_get_ts(hContact,pszProto,"Nick",&dbvNick);
						if (mir_tstrcmp(dbvNick.ptszVal, NULL) == 0)
						{
							db_free(&dbvNick);
							return FALSE;
						}

						msgLen += (int)mir_tstrlen(dbv.ptszVal);
						if (!db_get_ts(NULL,protocolname,KEY_HEADING,&dbvHead))
						{
							ptszTemp = dbvHead.ptszVal;
							ptszTemp.Replace(_T("%user%"), dbvNick.ptszVal);
							msgLen += (int)(mir_tstrlen(ptszTemp));
						}
						ptszTemp2 = (TCHAR*)mir_alloc(sizeof(TCHAR) * (msgLen+5));
						mir_sntprintf(ptszTemp2, msgLen+5, _T("%s\r\n\r\n%s"), ptszTemp.c_str(), dbv.ptszVal);
						if (ServiceExists(MS_VARS_FORMATSTRING))
						{
							FORMATINFO fi = { 0 };
							fi.cbSize = sizeof(fi);
							fi.flags = FIF_TCHAR;
							fi.tszFormat = ptszTemp2;
							ptszTemp = (TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
						}
						else ptszTemp = Utils_ReplaceVarsT(ptszTemp2);
						
						T2Utf pszUtf(ptszTemp);
						CallContactService(hContact, PSS_MESSAGE, 0, pszUtf);

						dbei.cbSize = sizeof(dbei);
						dbei.eventType = EVENTTYPE_MESSAGE;
						dbei.flags = DBEF_UTF | DBEF_SENT; //DBEF_READ;
						dbei.szModule = pszProto;
						dbei.timestamp = time(NULL);
						dbei.cbBlob = (int)mir_strlen(pszUtf) + 1;
						dbei.pBlob = (PBYTE)pszUtf;
						db_event_add(hContact, &dbei);

						mir_free(ptszTemp2);
						if (dbvNick.ptszVal)
							db_free(&dbvNick);
						if (dbvHead.ptszVal)
							db_free(&dbvHead);
					}
					db_free(&dbv);
				}
			}
		}

		db_set_dw(hContact,protocolname,"LastReplyTS",time(NULL));
		db_set_w(hContact,protocolname,"LastStatus",status);
	}
	return 0;
}
Пример #29
0
void TwitterProto::UpdateStatuses(bool pre_read, bool popups, bool tweetToMsg)
{
	try
	{
		ScopedLock s(twitter_lock_);
		twitter::status_list updates = twit_.get_statuses(200,since_id_);
		s.Unlock();
		if(!updates.empty()) {
			since_id_ = std::max(since_id_, updates[0].status.id);
		}

		for(twitter::status_list::reverse_iterator i=updates.rbegin(); i!=updates.rend(); ++i)
		{

			if(!pre_read && in_chat_)
				UpdateChat(*i);

			if(i->username == twit_.get_username())
				continue;

			HANDLE hContact = AddToClientList(i->username.c_str(),"");
			UpdateAvatar(hContact,i->profile_image_url); // as UpdateFriends() doesn't work at the moment, i'm going to update the avatars here

			// i think we maybe should just do that DBEF_READ line instead of stopping ALL this code.  have to test.
			if (tweetToMsg) {
				DBEVENTINFO dbei = {sizeof(dbei)};
				dbei.pBlob = (BYTE*)(i->status.text.c_str());
				dbei.cbBlob = (int)i->status.text.size()+1;
				dbei.eventType = TWITTER_DB_EVENT_TYPE_TWEET;
				dbei.flags = DBEF_UTF | DBEF_READ;
				dbei.timestamp = static_cast<DWORD>(i->status.time);
				dbei.szModule = m_szModuleName;
				db_event_add(hContact, &dbei);
			}

			db_set_utf(hContact,"CList","StatusMsg",i->status.text.c_str());

			if(!pre_read && popups)
				ShowContactPopup(hContact,i->status.text);
		}

		db_pod_set(0,m_szModuleName,TWITTER_KEY_SINCEID,since_id_);
		disconnectionCount = 0;
		debugLogA( _T("***** Status messages updated"));
	}
	catch(const bad_response &)
	{
		++disconnectionCount;
		debugLogA( _T("***** UpdateStatuses - Bad response from server, this has happened %d time(s)"), disconnectionCount);
		if (disconnectionCount > 2) {
			debugLogA( _T("***** UpdateStatuses - Too many bad responses from the server, signing off"));
			SetStatus(ID_STATUS_OFFLINE);
		}
	}
	catch(const std::exception &e)
	{
		ShowPopup( (std::string("While updating status messages, an error occurred: ")
			+e.what()).c_str());
		debugLogA( _T("***** Error updating status messages: %s"), e.what());
	}
}
Пример #30
0
INT_PTR CALLBACK DlgProcUrlSend(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	struct UrlSendData* dat = (struct UrlSendData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		Window_SetIcon_IcoLib(hwndDlg, SKINICON_EVENT_URL);
		Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact permanently to list"));
		Button_SetIcon_IcoLib(hwndDlg, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View user's details"));
		Button_SetIcon_IcoLib(hwndDlg, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View user's history"));
		Button_SetIcon_IcoLib(hwndDlg, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User menu"));

		SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_LIMITTEXT, 450, 0);
		dat = (struct UrlSendData*)mir_alloc(sizeof(struct UrlSendData));
		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
		dat->hContact = lParam;
		dat->hAckEvent = NULL;
		dat->hSendId = NULL;
		dat->sendBuffer = NULL;

		WindowList_Add(hUrlWindowList, hwndDlg, dat->hContact);
		{
			TCHAR *str = pcli->pfnGetContactDisplayName(dat->hContact, 0);
			SetDlgItemText(hwndDlg, IDC_NAME, str);
		}

		GetOpenBrowserUrls(hwndDlg, GetDlgItem(hwndDlg, IDC_URLS));
		SendDlgItemMessage(hwndDlg, IDC_URLS, CB_SETCURSEL, 0, 0);
		if (SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETCOUNT, 0, 0))SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_URLS, CBN_SELCHANGE), 0);
		EnableWindow(GetDlgItem(hwndDlg, IDOK), (SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETCURSEL, 0, 0) == CB_ERR)?FALSE:TRUE);
		Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "SRUrl", "send");
		mir_subclassWindow( GetDlgItem(hwndDlg, IDC_MESSAGE), SendEditSubclassProc);
		mir_subclassWindow( GetWindow(GetDlgItem(hwndDlg, IDC_URLS), GW_CHILD), SendEditSubclassProc);

		// From message dlg
		if ( !db_get_b(dat->hContact, "CList", "NotOnList", 0))
			ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE);

		SendMessage(hwndDlg, DM_UPDATETITLE, 0, 0);
		// From message dlg end
		return TRUE;

	case WM_DDE_DATA:
	case WM_DDE_ACK:
		return DdeMessage(hwndDlg, msg, wParam, lParam);

	case WM_TIMER:
		if (wParam == 0) {
			//ICQ sendurl timed out
			KillTimer(hwndDlg, 0);
			MessageBox(hwndDlg, TranslateT("Send timed out"), _T(""), MB_OK);
			EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_URLS), TRUE);
			SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETREADONLY, FALSE, 0);
		}
		break;

	case WM_MEASUREITEM:
		return Menu_MeasureItem((LPMEASUREITEMSTRUCT)lParam);

	case WM_DRAWITEM:
		{
			LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam;
			if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_PROTOCOL)) {
				char *szProto = GetContactProto(dat->hContact);
				if (szProto) {
					HICON hIcon = (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0);
					if (hIcon) {
						DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL);
						DestroyIcon(hIcon);
					}
				}
			}
		}
		return Menu_DrawItem((LPDRAWITEMSTRUCT)lParam);

	case DM_UPDATETITLE:
		sttUpdateTitle(hwndDlg, dat->hContact);
		break;

	case WM_COMMAND:
		if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact))
			break;

		switch (LOWORD(wParam)) {
		case IDOK:
			{
				char *body, *url;
				int bodySize, urlSize;

				urlSize = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_URLS))+1;
				url = (char*)mir_alloc(urlSize);
				GetDlgItemTextA(hwndDlg, IDC_URLS, url, urlSize);
				if (url[0] == 0) {
					mir_free(url);
					break;
				}
				bodySize = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE))+1;
				body = (char*)mir_alloc(bodySize);
				GetDlgItemTextA(hwndDlg, IDC_MESSAGE, body, bodySize);

				dat->sendBuffer = (char*)mir_realloc(dat->sendBuffer, mir_strlen(url)+mir_strlen(body)+2);
				mir_strcpy(dat->sendBuffer, url);
				mir_strcpy(dat->sendBuffer+mir_strlen(url)+1, body);
				dat->hAckEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT);
				dat->hSendId = (HANDLE)CallContactService(dat->hContact, PSS_URL, 0, (LPARAM)dat->sendBuffer);
				mir_free(url);
				mir_free(body);

				//create a timeout timer
				SetTimer(hwndDlg, 0, TIMEOUT_URLSEND, NULL);
				EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_URLS), FALSE);
				SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETREADONLY, TRUE, 0);

				return TRUE;
			}

		case IDCANCEL:
			DestroyWindow(hwndDlg);
			return TRUE;

		case IDC_URLS:
			if (HIWORD(wParam) == CBN_SELCHANGE) {
				int i, urlSize;
				char *title;
				i = SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETCURSEL, 0, 0);
				title = (char*)SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETITEMDATA, (WPARAM)i, 0);
				SetDlgItemTextA(hwndDlg, IDC_MESSAGE, title);
				urlSize = SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETLBTEXTLEN, (WPARAM)i, 0);
				EnableWindow(GetDlgItem(hwndDlg, IDOK), (urlSize>0));
			}
			else if (HIWORD(wParam) == CBN_EDITCHANGE) {
				int urlSize = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_URLS));
				EnableWindow(GetDlgItem(hwndDlg, IDOK), (urlSize>0));
			}
			break;
		case IDC_USERMENU:
			{
				RECT rc;
				HMENU hMenu = Menu_BuildContactMenu(dat->hContact);
				GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rc);
				TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL);
				DestroyMenu(hMenu);
			}
			break;

		case IDC_HISTORY:
			CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)dat->hContact, 0);
			break;

		case IDC_DETAILS:
			CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)dat->hContact, 0);
			break;

		case IDC_ADD:
			ADDCONTACTSTRUCT acs = {0};
			acs.hContact = dat->hContact;
			acs.handleType = HANDLE_CONTACT;
			acs.szProto = 0;
			CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs);

			if ( !db_get_b(dat->hContact, "CList", "NotOnList", 0))
				ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE);
		}
		break;

	case HM_EVENTSENT:
		{
			ACKDATA *ack = (ACKDATA*)lParam;
			if (ack->hProcess != dat->hSendId) break;
			if (ack->hContact != dat->hContact) break;
			if (ack->type != ACKTYPE_URL || ack->result != ACKRESULT_SUCCESS) break;

			DBEVENTINFO dbei = { 0 };
			dbei.cbSize = sizeof(dbei);
			dbei.eventType = EVENTTYPE_URL;
			dbei.flags = DBEF_SENT;
			dbei.szModule = GetContactProto(dat->hContact);
			dbei.timestamp = time(NULL);
			dbei.cbBlob = (DWORD)(mir_strlen(dat->sendBuffer)+mir_strlen(dat->sendBuffer+mir_strlen(dat->sendBuffer)+1)+2);
			dbei.pBlob = (PBYTE)dat->sendBuffer;
			db_event_add(dat->hContact, &dbei);
			KillTimer(hwndDlg, 0);
			DestroyWindow(hwndDlg);
		}
		break;

	case WM_DESTROY:
		Window_FreeIcon_IcoLib(hwndDlg);
		Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD);
		Button_FreeIcon_IcoLib(hwndDlg, IDC_DETAILS);
		Button_FreeIcon_IcoLib(hwndDlg, IDC_HISTORY);
		Button_FreeIcon_IcoLib(hwndDlg, IDC_USERMENU);

		WindowList_Remove(hUrlWindowList, hwndDlg);
		if (dat->hAckEvent) UnhookEvent(dat->hAckEvent);
		if (dat->sendBuffer != NULL) mir_free(dat->sendBuffer);
		mir_free(dat);
		Utils_SaveWindowPosition(hwndDlg, NULL, "SRUrl", "send");

		for (int i = SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETCOUNT, 0, 0)-1;i>=0;i--)
			mir_free((char*)SendDlgItemMessage(hwndDlg, IDC_URLS, CB_GETITEMDATA, i, 0));
		break;
	}

	return FALSE;
}