summaryrefslogtreecommitdiff
path: root/spamfilter/contact.c
diff options
context:
space:
mode:
Diffstat (limited to 'spamfilter/contact.c')
-rw-r--r--spamfilter/contact.c818
1 files changed, 818 insertions, 0 deletions
diff --git a/spamfilter/contact.c b/spamfilter/contact.c
new file mode 100644
index 0000000..6891b9c
--- /dev/null
+++ b/spamfilter/contact.c
@@ -0,0 +1,818 @@
+/*
+
+"Spam Filter"-Plugin for Miranda IM
+
+Copyright 2003-2006 Heiko Herkenrath
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program ("SpamFilter-License.txt"); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+// -- Includes
+#include "common.h"
+
+
+// -----------------------------------------
+
+
+WORD IncreasePreSpammerCount(SPAMCHECKDATA* pscd)
+{
+ WCHAR* pszUnique;
+ char* pszUniqueUtf8;
+ WORD sentSpam;
+
+ // Get UTF-8 encoded unique str
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (!pszUnique) return FALSE;
+ pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
+ mir_free(pszUnique);
+ if (!pszUniqueUtf8) return FALSE;
+
+ // Inc count
+ sentSpam = (WORD)DBGetContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, 0);
+ sentSpam++;
+ DBWriteContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, sentSpam);
+
+ mir_free(pszUniqueUtf8);
+
+ // Update "Auto-Ignore" button if options are opened
+ if (IsWindow(hwndSpamFilterOpt))
+ PostMessage(hwndSpamFilterOpt, SFM_CHECK_AUTOIGNORE, 0, 0);
+
+ return sentSpam;
+}
+
+WORD GetPreSpammerCount(SPAMCHECKDATA* pscd)
+{
+ WCHAR* pszUnique;
+ char* pszUniqueUtf8;
+ WORD sentSpam;
+
+ // Get UTF-8 encoded unique str
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (!pszUnique) return 0;
+ pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
+ mir_free(pszUnique);
+ if (!pszUniqueUtf8) return 0;
+
+ sentSpam = (WORD)DBGetContactSettingWord(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8, 0);
+ mir_free(pszUniqueUtf8);
+ return sentSpam;
+}
+
+BOOL RemovePreSpammerCount(SPAMCHECKDATA* pscd)
+{
+ WCHAR* pszUnique;
+ char* pszUniqueUtf8;
+ BOOL bReturn;
+
+ // Get UTF-8 encoded unique str
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (!pszUnique) return FALSE;
+ pszUniqueUtf8 = mir_utf8encodeW(pszUnique);
+ mir_free(pszUnique);
+ if (!pszUniqueUtf8) return FALSE;
+
+ bReturn = (DBDeleteContactSetting(NULL, DB_MODULE_NAME_PRESPAMMERS, pszUniqueUtf8) == 0);
+
+ // Update "Auto-Ignore" button if options are opened
+ if (IsWindow(hwndSpamFilterOpt))
+ PostMessage(hwndSpamFilterOpt, SFM_CHECK_AUTOIGNORE, 0, 0);
+
+ mir_free(pszUniqueUtf8);
+ return bReturn;
+}
+
+
+int MarkAllContactEventsUnRead(HANDLE hContact)
+{
+ int iReturn;
+ HANDLE* hDbEvents = NULL;
+ HANDLE* hDbEventsBuf;
+ int iEventCount;
+ HANDLE hDbEvent;
+ int i;
+ DBEVENTINFO dbei;
+
+ iReturn = 0;
+
+ // Loop through all events in the contact chain
+ iEventCount = 0;
+ for (hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0); hDbEvent; hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0))
+ {
+ // Store all events in memory
+ hDbEventsBuf = (HANDLE*)mir_realloc(hDbEvents, (iEventCount+1)*sizeof(HANDLE));
+ if (!hDbEventsBuf) break;
+ hDbEvents = hDbEventsBuf;
+ hDbEvents[iEventCount] = hDbEvent;
+ iEventCount++;
+ BOX2("cnt:%i, hndl:%i", iEventCount, hDbEvent);
+ }
+
+ // Add all old events back to the contact
+ for (i=0; i<iEventCount; i++)
+ {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvents[i], 0);
+ if (dbei.cbBlob <= 0) continue;
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
+ if (!dbei.pBlob) continue;
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvents[i], (LPARAM)&dbei) == 0)
+ {
+ switch (dbei.eventType)
+ {
+ case EVENTTYPE_AUTHREQUEST:
+ case EVENTTYPE_ADDED:
+ case EVENTTYPE_CONTACTS:
+ case EVENTTYPE_MESSAGE:
+ case EVENTTYPE_URL:
+ case EVENTTYPE_FILE:
+ {
+ if (!(dbei.flags&DBEF_SENT))
+ dbei.flags ^= DBEF_READ;
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvents[i]);
+
+ // Re-add event
+ BOX2("handle evnts: %i hdl:%i", i, hDbEvents[i]);
+ if (CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvents[i]) == 0)
+ if ((HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei) != NULL)
+ iReturn++;
+ break;
+ }
+ }
+ }
+
+ mir_free(dbei.pBlob);
+ }
+
+ // Authorization requests are stored under the main contact
+ // Loop through all events in the main chain
+ iEventCount = 0;
+ for (hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)NULL, 0); hDbEvent; hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0))
+ {
+ // Store all events in memory
+ hDbEventsBuf = (HANDLE*)mir_realloc(hDbEvents, (iEventCount+1)*sizeof(HANDLE));
+ if (!hDbEventsBuf) break;
+ hDbEvents = hDbEventsBuf;
+ hDbEvents[iEventCount] = hDbEvent;
+ iEventCount++;
+ }
+
+ // Add all old events back to the contact
+ for (i=0; i<iEventCount; i++)
+ {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvents[i], 0);
+ if (dbei.cbBlob <= 0) continue;
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob);
+ if (!dbei.pBlob) continue;
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvents[i], (LPARAM)&dbei) == 0)
+ {
+ if ((dbei.eventType == EVENTTYPE_AUTHREQUEST) || (dbei.eventType == EVENTTYPE_ADDED))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)))
+ {
+ if (*((PHANDLE)(dbei.pBlob+sizeof(DWORD))) == hContact)
+ {
+ if (!(dbei.flags&DBEF_SENT))
+ dbei.flags ^= DBEF_READ;
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvents[i]);
+
+ // Re-add event
+ if (CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvents[i]) == 0) // if successful
+ if ((HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei) != NULL)
+ iReturn++;
+ }
+ }
+ }
+ }
+
+ mir_free(dbei.pBlob);
+ }
+
+ if (hDbEvents) mir_free(hDbEvents);
+ return iReturn;
+}
+
+BOOL SendContactAutomatedMessage(HANDLE hContact, WCHAR* pszMessage, BOOL bAddToHistory)
+{
+ BOOL bReturn;
+ WCHAR* sendBuffer;
+ int bufSize;
+ char* pszProto;
+ int iSendRes;
+
+ if (!hContact || !pszMessage || (pszMessage[0] == _T('\0'))) return FALSE;
+ pszProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (!pszProto) return FALSE;
+
+ // Limit the message to max possible length
+ {
+ int iMaxLen = CallProtoService(pszProto, PS_GETCAPS, (WPARAM)PFLAG_MAXLENOFMESSAGE, (LPARAM)hContact);
+ if (iMaxLen != CALLSERVICE_NOTFOUND)
+ if ((int)lstrlen(pszMessage) > iMaxLen)
+ pszMessage[iMaxLen] = _T('\0');
+ }
+
+ // Construct message text
+ #if defined(UNICODE)
+ {
+ char* buf;
+ mir_utf8decode((char*)pszMessage,&sendBuffer);
+ if (!sendBuffer) return FALSE;
+ bufSize = lstrlenW(sendBuffer)+1;
+ bufSize *= sizeof(WCHAR)+1;
+ buf = (char*)mir_realloc(sendBuffer, bufSize);
+ if (!buf) {
+ mir_free(sendBuffer);
+ return FALSE;
+ }
+ }
+ #else
+ sendBuffer = pszMessage;
+ bufSize = lstrlen(pszMessage)+1;
+ #endif
+
+ // Send the message
+ #if defined(UNICODE)
+ if (pszProto) {
+ char szService[MAXMODULELABELLENGTH+10];
+ mir_snprintf(szService, ARRAYSIZE(szService), "%s%sW", pszProto, PSS_MESSAGE);
+ bReturn = ServiceExists(szService);
+ } else {
+ bReturn = FALSE;
+ }
+ iSendRes = CallContactService(hContact, bReturn?PSS_MESSAGE"W":PSS_MESSAGE, (WPARAM)PREF_UNICODE, (LPARAM)sendBuffer);
+ #else
+ iSendRes = CallContactService(hContact, PSS_MESSAGE, (WPARAM)0, (LPARAM)sendBuffer);
+ #endif
+ bReturn = ((iSendRes != CALLSERVICE_NOTFOUND) && (iSendRes != 0));
+
+ // Add the message to history
+ if (bReturn && bAddToHistory)
+ {
+ DBEVENTINFO dbei;
+
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.timestamp = time(NULL);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT;
+ dbei.szModule = pszProto;
+ dbei.cbBlob = bufSize; // Blob without terminating zero, but adding it though to avoid problems
+ dbei.pBlob = (PBYTE)sendBuffer;
+
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+ }
+
+ #if defined(UNICODE)
+ mir_free(sendBuffer);
+ #endif
+
+ return bReturn;
+}
+
+
+BOOL CreateContactListGroup(WCHAR* pszGroupName)
+{
+ int i;
+ char str[MAX_INT_LENGTH+1];
+ WCHAR name[256];
+ DBVARIANT dbv;
+
+ if (!pszGroupName) return FALSE;
+
+ for (i=0; ;i++)
+ {
+ mir_snprintf(str, ARRAYSIZE(str), "%i", i);
+ if (DBGetContactSettingTString(NULL, "CListGroups", str, &dbv) != 0)
+ break;
+ if (dbv.ptszVal[0] && !StrCmpI(dbv.ptszVal+1, pszGroupName)) {
+ DBFreeVariant(&dbv);
+ return FALSE;
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ name[0] = 1|GROUPF_EXPANDED;
+ mir_sntprintf(&name[1], ARRAYSIZE(name)-1, _T("%s"), pszGroupName);
+ DBWriteContactSettingTString(NULL, "CListGroups", str, name);
+ CallService(MS_CLUI_GROUPADDED, (WPARAM)i+1, 0);
+ return TRUE;
+}
+
+
+BOOL RemoveContactListGroup(WCHAR* pszGroupName)
+{
+ int i;
+ char str[MAX_INT_LENGTH+1];
+ DBVARIANT dbv;
+
+ if (!pszGroupName) return FALSE;
+ for (i=0; ;i++)
+ {
+ mir_snprintf(str, ARRAYSIZE(str), "%i", i);
+ if (DBGetContactSettingTString(NULL, "CListGroups", str, &dbv) != 0)
+ return FALSE;
+ if (dbv.ptszVal[0] && !StrCmpI(dbv.ptszVal+1, pszGroupName)) {
+ DBFreeVariant(&dbv);
+ break;
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ // Bring up confirm window
+ return (CallService(MS_CLIST_GROUPDELETE, (WPARAM)i+1, 0) == 0);
+}
+
+
+BOOL RemoveContactFromIgnoreList(HANDLE hContact)
+{
+ // Un-Ignore all events for the contact
+ BOOL bReturn = (CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, IGNOREEVENT_ALL) == 0);
+
+ // Remove group association
+ DBDeleteContactSetting(hContact, "CList", "Group");
+
+ // Restore NotOnList state
+ if (!DBGetContactSettingByte(hContact, DB_MODULE_NAME, "WasOnList", 0))
+ DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
+ DBDeleteContactSetting(hContact, DB_MODULE_NAME, "WasOnList");
+
+ // Unhide the contact
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+
+ // Re-Accept typing notifications
+ DBWriteContactSettingByte(hContact, "SRMM", "SupportTyping", 1);
+
+ // Restore not to appear as offline to the contact (back to normal mode)
+ CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)0, 0);
+
+ // Rename contact (to default name)
+ DBDeleteContactSetting(hContact, "CList", "MyHandle");
+ // Tell clist to refresh it's cache
+ CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, 0);
+
+ // NotifySpammerStateChanged will be called automatically on settings change
+ DBWriteContactSettingByte(hContact, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)FALSE);
+
+ return bReturn;
+}
+
+
+BOOL AddContactToIgnoreList(HANDLE hContact, BOOL bKeepHistory, BOOL bDenyAuthRequests, BOOL bNoLog)
+{
+ BOOL bReturn;
+ DBVARIANT dbv;
+
+ // NotifySpammerStateChanged will be called automatically on settings change
+ DBWriteContactSettingByte(hContact, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)TRUE);
+
+ // Ignore all events for the contact
+ bReturn = (CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, IGNOREEVENT_ALL) == 0);
+
+ if (DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ {
+ // Hide the contact
+ // (Hide it before removing NotOnList setting, so that no YouWereAdded notification is sent)
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_HIDEFROMCLIST, (BYTE)DEFAULT_SETTING_HIDEFROMCLIST))
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
+ else
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+
+ // Add permanently to list (after hide!!!)
+ DBDeleteContactSetting(hContact, "CList", "NotOnList");
+
+ // Remove association to a contactlist group (change to spammers)
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUP, (BYTE)DEFAULT_SETTING_MOVETOGROUP) &&
+ DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, &dbv) == 0)
+ {
+ CreateContactListGroup(dbv.ptszVal);
+ DBWriteContactSettingTString(hContact, "CList", "Group", dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ } else {
+ DBDeleteContactSetting(hContact, "CList", "Group");
+ }
+ } else {
+ DBWriteContactSettingByte(hContact, DB_MODULE_NAME, "WasOnList", 1);
+ }
+
+ // Do not send typing notifications
+ DBWriteContactSettingByte(hContact, "SRMM", "SupportTyping", 0);
+
+ // Appear as offline to the contact
+ CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)ID_STATUS_OFFLINE, 0);
+
+ // Rename contact
+ {
+ CONTACTINFO ci;
+
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+ #if defined(UNICODE)
+ ci.dwFlag = CNF_UNIQUEID|CNF_UNICODE;
+ #else
+ ci.dwFlag = CNF_UNIQUEID;
+ #endif
+
+ if (CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci) == 0)
+ {
+ WCHAR* pszUniqueID = NULL;
+
+ if (ci.type == CNFT_ASCIIZ) {
+ pszUniqueID = ci.pszVal; // mir_alloc used by MS_CONTACT_GETCONTACTINFO
+ } else if (ci.type == CNFT_DWORD) {
+ pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
+ if (pszUniqueID)
+ mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.dVal);
+ } else if (ci.type == CNFT_WORD) {
+ pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
+ if (pszUniqueID)
+ mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.wVal);
+ } else if (ci.type == CNFT_BYTE) {
+ pszUniqueID = (WCHAR*)mir_alloc((MAX_INT_LENGTH+1)*sizeof(WCHAR));
+ if (pszUniqueID)
+ mir_sntprintf(pszUniqueID, (MAX_INT_LENGTH+1), _T("%u"), ci.bVal);
+ }
+
+ if (pszUniqueID) {
+ DBWriteContactSettingTString(hContact, "CList", "MyHandle", pszUniqueID);
+ mir_free(pszUniqueID);
+ }
+ }
+/*
+ pszSuffix = TranslateT(" (Spammer)");
+ if (pszUniqueID && pszSuffix)
+ {
+ TCHAR* pszNewName = (TCHAR*)mir_alloc((lstrlen(pszUniqueID)+lstrlen(pszSuffix)+1)*sizeof(TCHAR));
+
+ if (pszNewName)
+ {
+ mir_sntprintf(pszNewName, lstrlen(pszUniqueID)+lstrlen(pszSuffix)+1, _T("%s%s"), pszUniqueID, pszSuffix);
+
+ DBWriteContactSettingTString(hContact, "CList", "MyHandle", pszNewName);
+
+ // Tell CList to refresh it's cache
+ CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, 0);
+
+ mir_free(pszNewName);
+ }
+ }
+*/
+ }
+
+ // Remove History (or mark read to get rid of pending "new message" notifications)
+ {
+ HANDLE hDbEvent, hDbEventBuf;
+
+ STRINGLIST* pslRecognition = NULL;
+ DBEVENTINFO dbei;
+ PBYTE pLogText;
+ WCHAR* pszUserName;
+ BOOL bDoWriteLog;
+
+ bDoWriteLog = !bNoLog && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, DEFAULT_SETTING_LOGGING);
+ if (bDoWriteLog)
+ {
+ pslRecognition = SLNewList();
+ SLAddItem(pslRecognition, TranslateT("Contact set as spammer"));
+ }
+
+ // ** History of the contact **
+ // hDbEvent gets buffered to allow deleting while enumerating (handle is offset)
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ hDbEvent = hDbEventBuf;
+
+ while (hDbEvent)
+ {
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+
+ // Now handle hDbEvent
+ {
+ if (bDoWriteLog || bDenyAuthRequests)
+ {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ if (dbei.cbBlob <= 0)
+ {
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob+sizeof(WCHAR)); // adding terminating zeros (security)
+ if (!dbei.pBlob)
+ {
+ // Ensure terminating zero
+ ZeroMemory(dbei.pBlob+dbei.cbBlob, sizeof(WCHAR));
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0) // if successful
+ {
+ if (!(dbei.flags&DBEF_SENT) && !(dbei.flags&DBEF_READ))
+ {
+ switch (dbei.eventType)
+ {
+ case EVENTTYPE_MESSAGE:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
+ {
+ #if defined(UNICODE)
+ // Checking if Unicode text available
+ if (dbei.cbBlob > lstrlenA((char*)dbei.pBlob))
+ pLogText = dbei.pBlob+(lstrlenA((char*)dbei.pBlob)+1)*sizeof(char);
+ else
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)dbei.pBlob);
+ #else
+ pLogText = dbei.pBlob;
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+ WriteToLogFile(dbei.szModule, SFMT_MESSAGE, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText)
+ if (dbei.cbBlob <= lstrlenA((char*)dbei.pBlob))
+ mir_free(pLogText);
+ #endif
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_URL:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_URL))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= 2*sizeof(char))
+ {
+ pLogText = dbei.pBlob+(lstrlenA((char*)dbei.pBlob)+1)*sizeof(char);
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_URL, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_FILE:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_FILE))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+3*sizeof(char)))
+ {
+ pLogText = dbei.pBlob+sizeof(DWORD); // hTransfer, filename(s)
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // description
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_FILE, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_CONTACTS:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_CONTACTS))
+ {
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_CONTACTS, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+ }
+ }
+ break;
+ }
+
+ case EVENTTYPE_AUTHREQUEST:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)+5*sizeof(char)))
+ {
+ pLogText = dbei.pBlob+sizeof(DWORD)+sizeof(HANDLE); // uin, hcontact, nick
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // first
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // last
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // email
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // reason
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_AUTHREQUEST, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+
+ // Deny authorisation
+ if (bDenyAuthRequests)
+ CallProtoService(dbei.szModule, PS_AUTHDENY, (WPARAM)hDbEvent, (LPARAM)NULL); // without reason
+
+ break;
+ }
+
+ case EVENTTYPE_ADDED:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_MESSAGE))
+ {
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_ADDED, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+ }
+ }
+ break;
+ }
+
+ } // switch
+ }
+
+ mir_free(dbei.pBlob);
+ }
+ }
+ }
+ }
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvent);
+
+ if (bKeepHistory)
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM)hContact, (LPARAM)hDbEvent);
+ else
+ CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvent);
+ }
+
+ hDbEvent = hDbEventBuf;
+ }
+
+ return TRUE;
+
+ // ** Main contact **
+ // Authorization Requests and Added Notifications are stored under the main contact
+ // hDbEvent gets buffered to allow deleting while enumerating (handle is offset)
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ hDbEvent = hDbEventBuf;
+
+ while (hDbEvent)
+ {
+ hDbEventBuf = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+
+ // Now handle hDbEvent
+ {
+ ZeroMemory(&dbei,sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ if (dbei.cbBlob < 0)
+ {
+ dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob+sizeof(WCHAR));
+ if (dbei.pBlob)
+ {
+ // Ensure terminating zero
+ ZeroMemory(dbei.pBlob+dbei.cbBlob, sizeof(WCHAR));
+
+ if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0)
+ {
+ if ((dbei.eventType == EVENTTYPE_AUTHREQUEST) || (dbei.eventType == EVENTTYPE_ADDED))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)))
+ {
+ if (*((PHANDLE)(dbei.pBlob+sizeof(DWORD))) == hContact)
+ {
+ if (bDoWriteLog || bDenyAuthRequests)
+ {
+ if (!(dbei.flags&DBEF_SENT) && !(dbei.flags&DBEF_READ))
+ {
+ switch (dbei.eventType)
+ {
+ case EVENTTYPE_AUTHREQUEST:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_AUTHREQUEST))
+ {
+ // DB event corrupt check
+ if (dbei.cbBlob >= (sizeof(DWORD)+sizeof(HANDLE)+5*sizeof(char)))
+ {
+ pLogText = dbei.pBlob+sizeof(DWORD)+sizeof(HANDLE); // uin, hcontact, nick
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // first
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // last
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // email
+ pLogText = pLogText+(lstrlenA((char*)pLogText)+1)*sizeof(char); // reason
+
+ #if defined(UNICODE)
+ pLogText = (PBYTE)mir_utf8encodeW((WCHAR*)pLogText);
+ #endif
+
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_AUTHREQUEST, pszUserName, (WCHAR*)pLogText, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+
+ #if defined(UNICODE)
+ if (pLogText) mir_free(pLogText);
+ #endif
+ }
+ }
+ }
+
+ // Deny authorisation
+ if (bDenyAuthRequests)
+ CallProtoService(dbei.szModule, PS_AUTHDENY, (WPARAM)hDbEvent, (LPARAM)NULL); // without reason
+
+ break;
+ }
+
+ case EVENTTYPE_ADDED:
+ {
+ if (bDoWriteLog)
+ {
+ if (!CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)dbei.szModule, (LPARAM)SFMT_ADDED))
+ {
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+
+ WriteToLogFile(dbei.szModule, SFMT_ADDED, pszUserName, NULL, pslRecognition, bKeepHistory ? SFF_MARKREAD : SFF_DELETE);
+ }
+ }
+ break;
+ }
+ } // switch
+ }
+ }
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hDbEvent);
+
+ if (bKeepHistory)
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM)hContact, (LPARAM)hDbEvent);
+ else
+ CallService(MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hDbEvent); }
+ }
+ }
+
+ }
+
+ mir_free(dbei.pBlob);
+ }
+ }
+
+ }
+
+ hDbEvent = hDbEventBuf;
+ }
+ }
+
+ return bReturn;
+}