/* "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= (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; }