summaryrefslogtreecommitdiff
path: root/spamfilter/services.c
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss123next@list.ru>2009-10-13 05:04:06 +0300
committerGluzskiy Alexandr <sss123next@list.ru>2009-10-13 05:04:06 +0300
commit227022d9ed977c75196725502847e0b371e4e879 (patch)
tree6fe79f5ae836fe4a974db459553eb6b46a1bf8eb /spamfilter/services.c
parent23d6d3e482927c13294f204b34ce23c6f445e8ac (diff)
spamfilter branchHEADmaster
Diffstat (limited to 'spamfilter/services.c')
-rw-r--r--spamfilter/services.c2038
1 files changed, 2038 insertions, 0 deletions
diff --git a/spamfilter/services.c b/spamfilter/services.c
new file mode 100644
index 0000000..188cf41
--- /dev/null
+++ b/spamfilter/services.c
@@ -0,0 +1,2038 @@
+/*
+
+"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"
+
+// -- Variables: Events/Hooks
+HANDLE hEventPreRegisterMessageType = NULL;
+HANDLE hEventOkToSpamCheck = NULL;
+HANDLE hEventOkToSpamDetection = NULL;
+HANDLE hEventSpamReceived = NULL;
+HANDLE hEventModuleLoaded = NULL;
+HANDLE hEventContactSpammerStateChanged = NULL;
+
+// -- Variables: Services
+HANDLE* hServices[19] = {NULL};
+
+
+// -----------------------------------------
+
+// Service: MS_SPAMFILTER_GETHANDLE
+static int ServiceGetHandle(WPARAM wParam, LPARAM lParam)
+{
+ switch ((UINT)wParam)
+ {
+ //case 1: return NULL; // hInstance was removed in v2.5.1.0
+
+ case SFHT_HWND_PLUGIN_OPTIONS: return IsWindow(hwndSpamFilterOpt) ? (int)hwndSpamFilterOpt : (int)NULL;
+ case SFHT_HWND_ADVERTISMENT_FILTER: return IsWindow(hwndAdvertismentFilter) ? (int)hwndAdvertismentFilter : (int)NULL;
+ case SFHT_HWND_ROBOT_FILTER: return IsWindow(hwndRobotFilter) ? (int)hwndRobotFilter : (int)NULL;
+ case SFHT_HWND_DISLIKEDMESSAGES_FILTER: return IsWindow(hwndDislikedMessagesFilter) ? (int)hwndDislikedMessagesFilter : (int)NULL;
+ case SFHT_HWND_SPAMDEFINITIONS_INFO: return IsWindow(hwndSpamDefinitionsInfo) ? (int)hwndSpamDefinitionsInfo : (int)NULL;
+ case SFHT_HWND_SPAMMERS_INFO: return IsWindow(hwndSpammersInfo) ? (int)hwndSpammersInfo : (int)NULL;
+
+ case SFHT_HICON_SPAM: return (int)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DEFAULT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ case SFHT_HICON_SPAM_LARGE: return (int)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DEFAULT_LARGE), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+ case SFHT_HICON_SPAM_LAYER: return (int)LoadImage(hInstance, MAKEINTRESOURCE(IDI_SPAM_LAYER), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+
+ case 100: // backward compatibility
+ #if defined(UNICODE)
+ case SFHT_BOOL_IS_UNICODE: return TRUE;
+ #else
+ case SFHT_BOOL_IS_UNICODE: return FALSE;
+ #endif
+
+ default: return (int)NULL;
+ }
+}
+
+
+// Service: MS_SPAMFILTER_SHOWERROR
+static int ServiceShowError(WPARAM wParam, LPARAM lParam)
+{
+ switch ((UINT)wParam)
+ {
+ case SFSE_CRITICAL_ERROR:
+ {
+ ShowInfoMessage(NIIF_ERROR, TranslateW("Spam Filter Critical Error"), TranslateW("A very critical internal error was detected!\r\nProbably the filter will not work at all.\r\n\r\nPlease update to the most current version if this problem persists."), 0);
+ return 0;
+ }
+
+ case SFSE_SEND_FAILED:
+ {
+ WCHAR* pszUserName;
+ if (lParam && (((SPAMCHECKDATA*)lParam)->cbSize < sizeof(SPAMCHECKDATA))) return 1;
+ pszUserName = lParam?SCD_GetContactCustomDisplayName((SPAMCHECKDATA*)lParam):NULL;
+ ShowInfoMessage(NIIF_WARNING, TranslateW("Spam Filter Error"), TranslateW("Spam Filter was not able to send an automated message to the user \"%s\"."), pszUserName?lstrlen(pszUserName):0, pszUserName?pszUserName:_T(""));
+ if (pszUserName) mir_free(pszUserName);
+ return 0;
+ }
+
+ default:
+ return 1;
+ }
+}
+
+
+// Service: MS_SPAMFILTER_COPYSPAMCHECKDATA
+static int ServiceCopySpamCheckData(WPARAM wParam, LPARAM lParam)
+{
+ SPAMCHECKDATA* to = (SPAMCHECKDATA*)wParam;
+ SPAMCHECKDATA* from = (SPAMCHECKDATA*)lParam;
+
+
+ if (!from || !to || (from && (from->cbSize < sizeof(SPAMCHECKDATA))) ) {
+ if (to) to->cbSize = sizeof(SPAMCHECKDATA);
+ return 1;
+ }
+ CopyMemory(to, from, from->cbSize);
+ if (to->pszMsgTypeName) to->pszMsgTypeName = mir_strdup(to->pszMsgTypeName);
+ if (to->pszMsgTypeSection) to->pszMsgTypeSection = mir_strdup(to->pszMsgTypeSection);
+ if (to->pszMsgText) {
+ if (to->dwFlags&SCDF_UNICODE)
+ to->pszMsgText = mir_strdup(to->pszMsgText);
+ else
+ to->pwszMsgText = mir_wstrdup(to->pwszMsgText);
+ }
+ if ((to->dwFlags&SCDF_NO_CONTACT) && to->pszUserName) {
+ if (to->dwFlags&SCDF_UNICODE)
+ to->pszUserName = mir_strdup(to->pszUserName);
+ else
+ to->pwszUserName = mir_wstrdup(to->pwszUserName);
+ }
+ to->cbSize = sizeof(SPAMCHECKDATA);
+ return 0;
+}
+
+
+// Service: MS_SPAMFILTER_FREESPAMCHECKDATA
+static int ServiceFreeSpamCheckData(WPARAM wParam, LPARAM lParam)
+{
+ SPAMCHECKDATA* pscd = (SPAMCHECKDATA*)wParam;
+
+ if (!pscd || (pscd->cbSize < sizeof(SPAMCHECKDATA))) return 1;
+ if (pscd->pszMsgTypeName) mir_free(pscd->pszMsgTypeName);
+ if (pscd->pszMsgTypeSection) mir_free(pscd->pszMsgTypeSection);
+ if (pscd->ptszMsgText) mir_free(pscd->ptszMsgText);
+ if ((pscd->dwFlags&SCDF_NO_CONTACT) && pscd->ptszUserName) mir_free(pscd->ptszUserName);
+ return 0;
+}
+
+
+// Service: MS_SPAMFILTER_SHOWFILTERDIALOG
+static int ServiceShowFilterDialog(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwndParent = (HWND)wParam;
+ DWORD dwFilterType = (DWORD)lParam;
+
+ if (dwFilterType&SFTEXF_SPAMDEFINITIONS_INFO)
+ {
+ INITCOMMONCONTROLSEX icc;
+
+ dwFilterType ^= SFTEXF_SPAMDEFINITIONS_INFO;
+ if ((dwFilterType != SFT_ADVERTISMENT_FILTER) && (dwFilterType != SFT_DISLIKEDMESSAGES_FILTER))
+ return 1;
+
+ if (IsWindow(hwndSpamDefinitionsInfo))
+ {
+ PostMessage(hwndSpamDefinitionsInfo, SFM_REFRESH_SPAMDEFINITIONS, (WPARAM)FALSE, (LPARAM)dwFilterType);
+ SetForegroundWindow(hwndSpamDefinitionsInfo);
+ return 0;
+ }
+
+ // Ensure the needed common controls are loaded
+ ZeroMemory(&icc, sizeof(icc));
+ icc.dwSize = sizeof(icc);
+ icc.dwICC = ICC_TAB_CLASSES|ICC_LISTVIEW_CLASSES;
+ InitCommonControlsEx(&icc);
+
+ if (hwndParent) {
+ // hwndSpamDefinitionsInfo will be set on WM_INITDIALOG and set to NULL on WM_DESTROY
+ // *** using ANSI version here because Hyperlink control of Miranda doesn't support Unicode ***
+ //return (DialogBoxParamA(hInstance, MAKEINTRESOURCEA(IDD_INFO_SPAMDEFINITIONS), hwndParent, DlgProcSpamDefinitionsInfo, dwFilterType)>0) ? 0 : 1;
+ return (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_INFO_SPAMDEFINITIONS), hwndParent, DlgProcSpamDefinitionsInfo, dwFilterType)>0) ? 0 : 1;
+
+ } else {
+ // *** using ANSI version here because Hyperlink control of Miranda doesn't (yet) support Unicode ***
+ //hwndSpamDefinitionsInfo = CreateDialogParamA(hInstance, MAKEINTRESOURCEA(IDD_INFO_SPAMDEFINITIONS), (HWND)NULL, DlgProcSpamDefinitionsInfo, dwFilterType);
+ hwndSpamDefinitionsInfo = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_INFO_SPAMDEFINITIONS), (HWND)NULL, DlgProcSpamDefinitionsInfo, dwFilterType);
+ return (hwndSpamDefinitionsInfo ? 0 : 1);
+ }
+
+ } else if (dwFilterType&SFTEXF_SPAMMERS_INFO)
+ {
+ dwFilterType ^= SFTEXF_SPAMMERS_INFO;
+ if (dwFilterType != SFTEX_OPTIONS_PAGE)
+ return 1;
+
+ if (IsWindow(hwndSpammersInfo)) {
+ SetForegroundWindow(hwndSpammersInfo);
+ return 0;
+ }
+
+ if (hwndParent) {
+ // hwndSpammersInfo will be set on WM_INITDIALOG and set to NULL on WM_DESTROY
+ return (DialogBox(hInstance, MAKEINTRESOURCE(IDD_INFO_SPAMMERS), hwndParent, DlgProcSpammersInfo)>0) ? 0 : 1;
+
+ } else {
+ hwndSpammersInfo = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_INFO_SPAMMERS), (HWND)NULL, DlgProcSpammersInfo);
+ return (hwndSpammersInfo ? 0 : 1);
+ }
+
+ } else {
+
+ switch (dwFilterType)
+ {
+ case SFTEX_OPTIONS_PAGE:
+ {
+ OPENOPTIONSDIALOG ood;
+
+ ZeroMemory(&ood, sizeof(ood));
+ ood.cbSize = sizeof(ood);
+ ood.pszGroup = Translate("Events");
+ ood.pszPage = Translate("Spam Filter");
+
+ return CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood);
+ }
+
+ case SFT_DISLIKEDMESSAGES_FILTER:
+ {
+ if (IsWindow(hwndDislikedMessagesFilter)) {
+ SetForegroundWindow(hwndDislikedMessagesFilter);
+ return 0;
+ }
+
+ if (hwndParent) {
+ // hwndDislikedMessagesFilter will be set on WM_INITDIALOG and set to NULL on WM_DESTROY
+ return (DialogBox(hInstance, MAKEINTRESOURCE(IDD_OPTIONS_CONFIGURE_DISLIKEDMESSAGEFILTER), hwndParent, DlgProcConfigureDislikedMessagesFilter)>0) ? 0 : 1;
+
+ } else {
+ hwndDislikedMessagesFilter = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_OPTIONS_CONFIGURE_DISLIKEDMESSAGEFILTER), (HWND)NULL, DlgProcConfigureDislikedMessagesFilter);
+ return (hwndDislikedMessagesFilter ? 0 : 1);
+ }
+ }
+
+ case SFT_ADVERTISMENT_FILTER:
+ {
+ INITCOMMONCONTROLSEX icc;
+
+ if (IsWindow(hwndAdvertismentFilter)) {
+ SetForegroundWindow(hwndAdvertismentFilter);
+ return 0;
+ }
+
+ // Ensure the needed common controls are loaded
+ ZeroMemory(&icc, sizeof(icc));
+ icc.dwSize = sizeof(icc);
+ icc.dwICC = ICC_UPDOWN_CLASS;
+ InitCommonControlsEx(&icc);
+
+ if (hwndParent) {
+ // hwndAdvertismentFilter will be set on WM_INITDIALOG and set to NULL on WM_DESTROY
+ return (DialogBox(hInstance, MAKEINTRESOURCE(IDD_OPTIONS_CONFIGURE_ADVERTISMENTFILTER), hwndParent, DlgProcConfigureAdvertismentFilter)>0) ? 0 : 1;
+
+ } else {
+ hwndAdvertismentFilter = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_OPTIONS_CONFIGURE_ADVERTISMENTFILTER), (HWND)NULL, DlgProcConfigureAdvertismentFilter);
+ return (hwndAdvertismentFilter ? 0 : 1);
+ }
+ }
+
+ case SFT_ROBOT_FILTER:
+ {
+ if (IsWindow(hwndRobotFilter)) {
+ SetForegroundWindow(hwndRobotFilter);
+ return 0;
+ }
+
+ if (hwndParent) {
+ // hwndRobotFilter will be set on WM_INITDIALOG and set to NULL on WM_DESTROY
+ return (DialogBox(hInstance, MAKEINTRESOURCE(IDD_OPTIONS_CONFIGURE_ROBOTFILTER), hwndParent, DlgProcConfigureRobotFilter)>0) ? 0 : 1;
+
+ } else {
+ hwndRobotFilter = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_OPTIONS_CONFIGURE_ROBOTFILTER), (HWND)NULL, DlgProcConfigureRobotFilter);
+ return (hwndRobotFilter ? 0 : 1);
+ }
+ }
+
+ default:
+ return 1;
+ }
+
+ }
+}
+
+
+// Service: MS_SPAMFILTER_RESETAUTOIGNORE
+static int EnumAutoIgnoreSettingsProc(const char* pszSetting, LPARAM lParam)
+{
+ WCHAR* pszBuf;
+ mir_utf8decode((char*)pszSetting,&pszBuf);
+ if (pszBuf) {
+ SLAddItem((STRINGLIST*)lParam, pszBuf);
+ mir_free(pszBuf);
+ }
+ return 0;
+}
+
+static int ServiceResetAutoIgnore(WPARAM wParam, LPARAM lParam)
+{
+ BOOL bOnlyCount = (BOOL)wParam;
+
+ int iReturn;
+ DBCONTACTENUMSETTINGS dbces;
+ STRINGLIST* pslSettings = SLNewList();
+ int i;
+ #if defined(UNICODE)
+ char* pszBuf;
+ #endif
+
+ // Enum settings
+ dbces.szModule = DB_MODULE_NAME_PRESPAMMERS;
+ dbces.pfnEnumProc = EnumAutoIgnoreSettingsProc;
+ dbces.lParam = (LPARAM)pslSettings;
+
+ CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)NULL, (LPARAM)&dbces);
+
+ // Delete settings
+ if (!bOnlyCount)
+ {
+ iReturn = 0;
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(pslSettings); i++)
+ {
+ #if defined(UNICODE)
+ pszBuf = mir_utf8encodeW(SLGetItem(pslSettings, i));
+ if (pszBuf)
+ {
+ if (DBDeleteContactSetting(NULL, dbces.szModule, pszBuf) != 0)
+ iReturn++;
+ }
+ #else
+ if (DBDeleteContactSetting(NULL, dbces.szModule, SLGetItem(pslSettings, i)) != 0)
+ iReturn++;
+ #endif
+ }
+ } else {
+ iReturn = SLGetItemCount(pslSettings);
+ }
+
+ // Free memory
+ SLFreeList(pslSettings);
+
+ return iReturn;
+}
+
+
+// Service: MS_SPAMFILTER_CONTACT_SETASSPAMMER
+static int ServiceContactSetAsSpammer(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ DWORD dwFlags = (DWORD)lParam;
+
+ if (!hContact || (hContact == INVALID_HANDLE_VALUE)) return 1;
+
+ if (dwFlags & SCASF_NO_NOTIFY)
+ {
+ if (dwFlags & SCASF_USE_ROBOT_SOUND)
+ SkinPlaySound(DB_SOUND_ROBOT_SETTING);
+ else
+ SkinPlaySound(DB_SOUND_ADVERTISMENT_SETTING);
+ }
+
+ // Add contact to spammer list
+ AddContactToIgnoreList(hContact, !(dwFlags&SCASF_NO_REMOVE_HISTORY), !(dwFlags&SCASF_NO_DENY_AUTHREQUESTS), (dwFlags & SCASF_NO_NOTIFY));
+
+ // Remove pre-spammer flag if exists (now is real spammer)
+ {
+ SPAMCHECKDATA scd;
+
+ ZeroMemory(&scd, sizeof(scd));
+ scd.cbSize = sizeof(scd);
+ scd.hContact = hContact;
+
+ RemovePreSpammerCount(&scd);
+ }
+
+ return 0;
+}
+
+
+// Service: MS_SPAMFILTER_CONTACT_SHOWSETASSPAMMERDIALOG
+static int ServiceContactShowSetAsSpammerDialog(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ HWND hwndParent = (HWND)lParam;
+ BOOL bDlgOK;
+
+ WCHAR* pszFmt;
+ WCHAR* pszUserName;
+ MSGBOXPARAMS mbp;
+
+ if (!hContact || (hContact == INVALID_HANDLE_VALUE)) return 1;
+
+ // Correct wrong call (backward compatibility)
+ if (hwndParent == INVALID_HANDLE_VALUE) hwndParent = NULL;
+
+ ZeroMemory(&mbp, sizeof(mbp));
+ mbp.cbSize = sizeof(mbp);
+ mbp.dwLanguageId = LANGIDFROMLCID(GetThreadLocale()); // Current system language: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
+ mbp.hwndOwner = hwndParent;
+ mbp.hInstance = hInstance;
+ mbp.lpszIcon = MAKEINTRESOURCE(IDI_DEFAULT_LARGE);
+ mbp.dwStyle = MB_USERICON|MB_YESNO|MB_DEFBUTTON1|MB_SETFOREGROUND|MB_TASKMODAL; // MB_RTLREADING works also on non-arabic systems (Win 2000/XP)
+ mbp.lpszCaption = TranslateW("Mark Contact as Spammer");
+ pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
+ pszFmt = TranslateW("Are you sure that the contact \"%s\" shall be marked as spammer?\r\n\r\nMarking a contact as spammer means that all associated messages will be recognized as spam and the contact will be completely ignored in the future.\r\n\r\nA contact that was marked as spammer can be restored using the options dialog.");
+ mbp.lpszText = (WCHAR*)mir_alloc((lstrlen(pszFmt)+(pszUserName?lstrlen(pszUserName):0)+1)*sizeof(WCHAR));
+ mir_sntprintf((WCHAR*)mbp.lpszText, (lstrlen(pszFmt) + (pszUserName?lstrlen(pszUserName):0) + 1), pszFmt, pszUserName?pszUserName:_T(""));
+
+ bDlgOK = (MessageBoxIndirect(&mbp) == IDYES);
+ if ((char*)mbp.lpszText) mir_free((char*)mbp.lpszText);
+
+ if (bDlgOK)
+ {
+ BOOL bNoLog;
+ BOOL bKeepHistory;
+
+ // Get mark-read / delete setting
+ bKeepHistory = ((DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_BEHAVIOUR, DEFAULT_SETTING_BEHAVIOUR) == 1) ? TRUE : FALSE);
+
+ // Check id ctrl key is pressed to manually cancel logging
+ if (GetAsyncKeyState(VK_CONTROL)&0x8000)
+ bNoLog = FALSE;
+ else
+ bNoLog = TRUE;
+
+ SkinPlaySound(DB_SOUND_ADVERTISMENT_SETTING);
+
+ // Add contact to spammer list
+ AddContactToIgnoreList(hContact, bKeepHistory, TRUE, bNoLog);
+
+ // Remove pre-spammer flag (now is real spammer)
+ {
+ SPAMCHECKDATA scd;
+
+ ZeroMemory(&scd, sizeof(scd));
+ scd.cbSize = sizeof(scd);
+ scd.hContact = hContact;
+
+ RemovePreSpammerCount(&scd);
+ }
+ }
+
+ return (int)bDlgOK;
+}
+
+
+// Service: MS_SPAMFILTER_CONTACT_ISSPAMMER
+static int ServiceContactIsSpammer(WPARAM wParam, LPARAM lParam)
+{
+ return (BYTE)(DBGetContactSettingByte((HANDLE)wParam, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)FALSE)?TRUE:FALSE);
+}
+
+
+// Service: MS_SPAMFILTER_CONTACT_UNSETSPAMMER
+static int ServiceContactUnSetSpammer(WPARAM wParam, LPARAM lParam)
+{
+ // Internal note: lParam is hwndParent when used as menu item service
+
+ if ((HANDLE)wParam && ((HANDLE)wParam != INVALID_HANDLE_VALUE) )
+ return RemoveContactFromIgnoreList((HANDLE)wParam) ? 0 : 1;
+ else
+ return 1;
+}
+
+
+// Service: MS_SPAMFILTER_CHANGEFILTERACTIVATION
+static int ServiceChangeFilterActivation(WPARAM wParam, LPARAM lParam)
+{
+ BOOL bNewStatus = (BOOL)lParam;
+ DWORD dwFilterType = (DWORD)wParam;
+
+ switch (dwFilterType)
+ {
+ case SFT_DISLIKEDMESSAGES_FILTER:
+ {
+ if (IsWindow(hwndSpamFilterOpt))
+ CheckDlgButton(hwndSpamFilterOpt, IDC_CHECKBOX_DISLIKEDMESSAGEFILTER, (bNewStatus ? BST_CHECKED : BST_UNCHECKED));
+
+ return DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, (BYTE)bNewStatus);
+ }
+
+ case SFT_ADVERTISMENT_FILTER:
+ {
+ if (IsWindow(hwndSpamFilterOpt))
+ CheckDlgButton(hwndSpamFilterOpt, IDC_CHECKBOX_ADVERTISMENTFILTER, (bNewStatus ? BST_CHECKED : BST_UNCHECKED));
+
+ return DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)bNewStatus);
+ }
+
+ case SFT_ROBOT_FILTER:
+ {
+ if (IsWindow(hwndSpamFilterOpt))
+ CheckDlgButton(hwndSpamFilterOpt, IDC_CHECKBOX_ROBOTFILTER, (bNewStatus ? BST_CHECKED : BST_UNCHECKED));
+
+ return DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)bNewStatus);
+ }
+
+ default:
+ return 1;
+ }
+}
+
+
+// Service: MS_SPAMFILTER_GETSPAMCHECKINFO
+static int ServiceGetSpamCheckInfo(WPARAM wParam, LPARAM lParam)
+{
+ DWORD dwInfoType = (DWORD)wParam;
+
+ switch (dwInfoType)
+ {
+ case SFSCI_ACTIVATION_FILTER:
+ {
+ switch ((DWORD)lParam)
+ {
+ case SFT_DISLIKEDMESSAGES_FILTER:
+ return (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, DEFAULT_SETTING_DISLIKEDMESSAGEFILTER)?TRUE:FALSE);
+
+ case SFT_ADVERTISMENT_FILTER:
+ return (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, DEFAULT_SETTING_ADVERTISMENTFILTER)?TRUE:FALSE);
+
+ case SFT_ROBOT_FILTER:
+ return (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, DEFAULT_SETTING_ROBOTFILTER)?TRUE:FALSE);
+ }
+
+ break;
+ }
+
+ case SFSCI_ADD_TO_HISTORY:
+ {
+ switch ((DWORD)lParam)
+ {
+ // Disliked Messages Filter
+ case SFSCI_MSGTEXT_NOTIFYA:
+ case SFSCI_MSGTEXT_NOTIFYW:
+ return (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_ADDTOHISTORY, DEFAULT_SETTING_DISLIKEDMESSAGE_ADDTOHISTORY)?TRUE:FALSE);
+
+ // Robot Filter
+ case SFSCI_MSGTEXT_INSTRUCTIONA:
+ case SFSCI_MSGTEXT_INSTRUCTIONW:
+ return (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ADDTOHISTORY, DEFAULT_SETTING_ROBOT_ADDTOHISTORY)?TRUE:FALSE);
+
+ case SFSCI_MSGTEXT_CONFIRMATIONA:
+ case SFSCI_MSGTEXT_CONFIRMATIONW:
+ return (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ADDTOHISTORY, DEFAULT_SETTING_ROBOT_ADDTOHISTORY)?TRUE:FALSE);
+ }
+ }
+
+ case SFSCI_MSGTEXT_NOTIFYA:
+ case SFSCI_MSGTEXT_INSTRUCTIONA:
+ case SFSCI_MSGTEXT_CONFIRMATIONA:
+ case SFSCI_MSGTEXT_NOTIFYW:
+ case SFSCI_MSGTEXT_INSTRUCTIONW:
+ case SFSCI_MSGTEXT_CONFIRMATIONW:
+ {
+ SPAMCHECKDATA* pscd = (SPAMCHECKDATA*)lParam;
+ char* pszSetting;
+ WCHAR* pszBuf;
+ WCHAR* pReturn;
+ DBVARIANT dbv;
+ STRINGLIST* pslFromTo;
+
+ if (!pscd || (pscd->cbSize < sizeof(SPAMCHECKDATA)) || !SCD_IsUserValid(pscd))
+ break;
+
+ switch (dwInfoType)
+ {
+ // Disliked Messages Filter
+ case SFSCI_MSGTEXT_NOTIFYA:
+ case SFSCI_MSGTEXT_NOTIFYW:
+ pszSetting = DB_SETTING_DISLIKEDMESSAGE_RETURNMESSAGE; // readonly allocated
+ break;
+
+ // Robot Filter
+ case SFSCI_MSGTEXT_INSTRUCTIONA:
+ case SFSCI_MSGTEXT_INSTRUCTIONW:
+ pszSetting = DB_SETTING_ROBOT_INSTRUCTION; // readonly allocated
+ break;
+
+ case SFSCI_MSGTEXT_CONFIRMATIONA:
+ case SFSCI_MSGTEXT_CONFIRMATIONW:
+ pszSetting = DB_SETTING_ROBOT_CONFIRMATION; // readonly allocated
+ break;
+
+ default:
+ pszSetting = NULL;
+ }
+
+ if (pszSetting)
+ {
+ WCHAR* pszVariablesOut = NULL;
+ pslFromTo = SLNewList();
+
+ if ((dwInfoType != SFSCI_MSGTEXT_NOTIFYA) && (dwInfoType != SFSCI_MSGTEXT_NOTIFYW))
+ {
+ // %securitycode%
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, &dbv) == 0)
+ {
+ SLAddItemPair(pslFromTo, _T("%securitycode%"), dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ } else {
+ WCHAR szRnd[RANDOM_ANSWER_LENGTH+1];
+ GetRandomString(szRnd, ARRAYSIZE(szRnd));
+ DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, szRnd);
+ SLAddItemPair(pslFromTo, _T("%securitycode%"), szRnd);
+ }
+
+ // %triesleft%
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_AUTOADDSPAMMERS, DEFAULT_SETTING_AUTOADDSPAMMERS))
+ {
+ WCHAR szTriesLeft[MAX_INT_LENGTH+1];
+ mir_sntprintf(szTriesLeft, ARRAYSIZE(szTriesLeft), _T("%u"), DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ALLOWEDSPAMMESSAGES, DEFAULT_SETTING_ALLOWEDSPAMMESSAGES)-GetPreSpammerCount(pscd)+1);
+ SLAddItemPair(pslFromTo, _T("%triesleft%"), szTriesLeft);
+ } else {
+ SLAddItemPair(pslFromTo, _T("%triesleft%"), TranslateW("unlimited"));
+ }
+ }
+
+ // %message%
+ #if defined(UNICODE)
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszBuf = pscd->ptszMsgText;
+ else
+ pszBuf = (WCHAR*)mir_utf8encodeW((WCHAR*)pscd->pszMsgText);
+
+ SLAddItemPair(pslFromTo, _T("%message%"), pszBuf);
+
+ if (pszBuf && !(pscd->dwFlags&SCDF_UNICODE))
+ mir_free(pszBuf);
+ #else
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszBuf = UnicodeToAnsi(pscd->pwszMsgText);
+ else
+ pszBuf = pscd->ptszMsgText;
+
+ SLAddItemPair(pslFromTo, _T("%message%"), pszBuf);
+
+ if ((pscd->dwFlags&SCDF_UNICODE) && pszBuf)
+ mir_free(pszBuf);
+ #endif
+
+ // %sender%
+ pszBuf = SCD_GetContactName(pscd, FALSE);
+ SLAddItemPair(pslFromTo, _T("%sender%"), pszBuf);
+ if (pszBuf) mir_free(pszBuf);
+
+ // Retrieve message text
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, pszSetting, &dbv) == 0) {
+ pszBuf = ReplaceSubStringWithStringMultiple(dbv.ptszVal, pslFromTo, TRUE, FALSE, NULL);
+ DBFreeVariant(&dbv);
+ } else {
+ pszBuf = NULL;
+ }
+
+ // Retrieve message text
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, pszSetting, &dbv) == 0) {
+ pszBuf = ReplaceSubStringWithStringMultiple(dbv.ptszVal, pslFromTo, TRUE, FALSE, NULL);
+ DBFreeVariant(&dbv);
+ } else {
+ pszBuf = NULL;
+ }
+ SLFreeList(pslFromTo);
+
+ // Support for "Variables" plugin
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.flags = FIF_UNICODE;
+ fi.tszFormat = pszBuf;
+ fi.tszExtraText = pscd->ptszMsgText; // %message% variable is handled earlier by Spam Filter itself
+ fi.hContact = (pscd->dwFlags&SCDF_NO_CONTACT)?NULL:pscd->hContact;
+
+ pszVariablesOut = (WCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ }
+
+
+ // Convert return value
+ pReturn = NULL;
+ if (pszVariablesOut?pszVariablesOut:pszBuf)
+ {
+ switch (dwInfoType)
+ {
+ case SFSCI_MSGTEXT_NOTIFYA:
+ case SFSCI_MSGTEXT_INSTRUCTIONA:
+ case SFSCI_MSGTEXT_CONFIRMATIONA:
+ {
+ #if defined(UNICODE)
+ // UnicodeToAnsi uses mir_alloc
+ mir_utf8decode((char*)pszVariablesOut?(char*)pszVariablesOut:(char*)pszBuf,&pReturn);
+ #else
+ // AnsiDup uses mir_alloc
+ pReturn = (PBYTE)mir_strdup(pszVariablesOut?pszVariablesOut:pszBuf);
+ #endif
+ break;
+ }
+
+ case SFSCI_MSGTEXT_NOTIFYW:
+ case SFSCI_MSGTEXT_INSTRUCTIONW:
+ case SFSCI_MSGTEXT_CONFIRMATIONW:
+ {
+ #if defined(UNICODE)
+ // UnicodeDup uses mir_alloc
+ pReturn = mir_wstrdup(pszVariablesOut?pszVariablesOut:pszBuf);
+ #else
+ // mir_utf8encodeW uses mir_alloc
+ pReturn = (PBYTE)mir_utf8encodeW(pszVariablesOut?pszVariablesOut:pszBuf);
+ #endif
+ break;
+ }
+ }
+ }
+
+
+ if (pszBuf)
+ SLFreeReturn(pszBuf);
+
+ // Support for "Variables" plugin
+ if (pszVariablesOut)
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)pszVariablesOut, 0);
+
+ return (int)pReturn;
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+// Service: MS_SPAMFILTER_REGISTERMESSAGETYPE
+static int ServiceRegisterMessageType(WPARAM wParam, LPARAM lParam)
+{
+ MESSAGETYPEDESC* pmtdNew = (MESSAGETYPEDESC*)lParam;
+
+ if (!pmtdNew->pszName || !pmtdNew->pszSection || (pmtdNew->cbSize < MESSAGETYPEDESC_V2000_SIZE))
+ return 1;
+
+ // Do not add if already added
+ EnterCriticalSection(&csMsgTypes); // thread safety
+ if (GetMsgTypeID(pmtdNew->pszSection, pmtdNew->pszName) >= 0) {
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return 1;
+ }
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+
+ // outside critical section:
+ // Hand out event (asking other plugins if default data is ok)
+ if (NotifyEventHooks(hEventPreRegisterMessageType, (WPARAM)wParam, (LPARAM)lParam) == 1) {
+ OutputDebugString(_T("Spam Filter: Adding message type denied (by event).\r\n"));
+ return 1;
+ }
+
+ // Do not add if already added (check again)
+ EnterCriticalSection(&csMsgTypes); // thread safety
+ if (GetMsgTypeID(pmtdNew->pszSection, pmtdNew->pszName) >= 0) {
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return 1;
+ }
+
+ // Resize list array
+ {
+ MESSAGETYPEDESC* pamtdMsgTypesBuf;
+ pamtdMsgTypesBuf = (MESSAGETYPEDESC*)mir_realloc(pamtdMsgTypes, (uMsgTypesCount+1)*sizeof(MESSAGETYPEDESC));
+
+ if (pamtdMsgTypesBuf) {
+ pamtdMsgTypes = pamtdMsgTypesBuf;
+ } else {
+ // Fatal error: list was not reallocated, insufficient memory (old data still valid)
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return 1;
+ }
+ }
+
+ pamtdMsgTypes[uMsgTypesCount].cbSize = sizeof(MESSAGETYPEDESC);
+ pamtdMsgTypes[uMsgTypesCount].dwFlags = pmtdNew->dwFlags;
+
+ // Backward compatibility (struct extended in v2.1.1.0)
+ if (pmtdNew->cbSize > MESSAGETYPEDESC_V2000_SIZE) {
+ pamtdMsgTypes[uMsgTypesCount].iPosition = pmtdNew->iPosition;
+ pamtdMsgTypes[uMsgTypesCount].iSectionPosition = pmtdNew->iSectionPosition;
+ } else {
+ pamtdMsgTypes[uMsgTypesCount].iPosition = 0;
+ pamtdMsgTypes[uMsgTypesCount].iSectionPosition = pmtdNew->iSectionPosition;
+ }
+
+ pamtdMsgTypes[uMsgTypesCount].pszSection = mir_strdup(pmtdNew->pszSection);
+ pamtdMsgTypes[uMsgTypesCount].pszName = mir_strdup(pmtdNew->pszName);
+
+ #if defined(UNICODE)
+ if (pmtdNew->dwFlags&MTDF_UNICODE) {
+ pamtdMsgTypes[uMsgTypesCount].ptszSectionDescription = pmtdNew->pwszSectionDescription ? mir_wstrdup(pmtdNew->pwszSectionDescription) : (WCHAR*)mir_utf8encodeW((WCHAR*)Translate((WCHAR*)pmtdNew->pszSection));
+ pamtdMsgTypes[uMsgTypesCount].ptszDescription = pmtdNew->pwszDescription ? mir_wstrdup(pmtdNew->pwszDescription) : (WCHAR*)mir_utf8encodeW((WCHAR*)Translate((WCHAR*)pmtdNew->pszName));
+ } else {
+ pamtdMsgTypes[uMsgTypesCount].dwFlags |= MTDF_UNICODE;
+ pamtdMsgTypes[uMsgTypesCount].ptszSectionDescription = pmtdNew->pszSectionDescription ? (WCHAR*)mir_utf8encodeW((WCHAR*)pmtdNew->pszSectionDescription) : (WCHAR*)mir_utf8encodeW((WCHAR*)Translate((WCHAR*)pmtdNew->pszSection));
+ pamtdMsgTypes[uMsgTypesCount].ptszDescription = pmtdNew->pszDescription ? (WCHAR*)mir_utf8encodeW((WCHAR*)pmtdNew->pszDescription) : (WCHAR*)mir_utf8encodeW((WCHAR*)Translate((WCHAR*)pmtdNew->pszName));
+ }
+ #else
+ if (pmtdNew->dwFlags&MTDF_UNICODE) {
+ pamtdMsgTypes[uMsgTypesCount].dwFlags ^= MTDF_UNICODE;
+ pamtdMsgTypes[uMsgTypesCount].ptszSectionDescription = pmtdNew->pwszSectionDescription ? UnicodeToAnsi(pmtdNew->pwszSectionDescription) : mir_strdup(Translate(pmtdNew->pszSection));
+ pamtdMsgTypes[uMsgTypesCount].ptszDescription = pmtdNew->pwszDescription ? UnicodeToAnsi(pmtdNew->pwszDescription) : mir_strdup(Translate(pmtdNew->pszName));
+ } else {
+ pamtdMsgTypes[uMsgTypesCount].ptszSectionDescription = pmtdNew->pszSectionDescription ? AnsiDup(pmtdNew->pszSectionDescription) : AnsiDup(Translate(pmtdNew->pszSection));
+ pamtdMsgTypes[uMsgTypesCount].ptszDescription = pmtdNew->pszDescription ? AnsiDup(pmtdNew->ptszDescription) : AnsiDup(Translate(pmtdNew->pszName));
+ }
+ #endif
+
+ // Fatal error (strings were not allocated, insufficient memory)
+ if (!pamtdMsgTypes[uMsgTypesCount].pszSection || !pamtdMsgTypes[uMsgTypesCount].pszSectionDescription || !pamtdMsgTypes[uMsgTypesCount].pszName || !pamtdMsgTypes[uMsgTypesCount].pszDescription)
+ {
+ if (pamtdMsgTypes[uMsgTypesCount].pszSection) mir_free(pamtdMsgTypes[uMsgTypesCount].pszSection);
+ if (pamtdMsgTypes[uMsgTypesCount].pszSectionDescription) mir_free(pamtdMsgTypes[uMsgTypesCount].pszSectionDescription);
+ if (pamtdMsgTypes[uMsgTypesCount].pszName) mir_free(pamtdMsgTypes[uMsgTypesCount].pszName);
+ if (pamtdMsgTypes[uMsgTypesCount].pszDescription) mir_free(pamtdMsgTypes[uMsgTypesCount].pszDescription);
+
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return 1;
+ }
+
+ pamtdMsgTypes[uMsgTypesCount].hSectionIcon = pmtdNew->hSectionIcon ? (HICON)CopyImage(pmtdNew->hSectionIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE) : NULL;
+
+ if ((int)pmtdNew->hIcon < 0) // if is miranda skinned icon constant
+ pamtdMsgTypes[uMsgTypesCount].hIcon = pmtdNew->hIcon;
+ else
+ pamtdMsgTypes[uMsgTypesCount].hIcon = pmtdNew->hIcon ? (HICON)CopyImage(pmtdNew->hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE) : NULL;
+
+
+ uMsgTypesCount++;
+
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+
+ // Refresh shown list
+ if (IsWindow(hwndSpamFilterOpt))
+ SendMessage(hwndSpamFilterOpt, SFM_REBUILD_MSGTYPES, 0, 0);
+
+ return 0;
+}
+
+
+// Service: MS_SPAMFILTER_REMOVEMESSAGETYPE
+static int ServiceRemoveMessageType(WPARAM wParam, LPARAM lParam)
+{
+ char* pszMsgTypeSection = (char*)wParam;
+ char* pszMsgTypeName = (char*)lParam;
+
+ MESSAGETYPEDESC* pamtdMsgTypesBuf;
+ int iReturn;
+ char* pszSetting;
+ unsigned int u;
+
+ if (!pszMsgTypeName || !pszMsgTypeSection) return 1;
+ iReturn = 1;
+
+ EnterCriticalSection(&csMsgTypes); // thread safety
+
+ // Remove array item
+ if (pamtdMsgTypes)
+ {
+ for (u=0; u<uMsgTypesCount; u++)
+ {
+ // Same pszSection?
+ if (StrCmpA(pamtdMsgTypes[u].pszSection, pszMsgTypeSection) == 0)
+ {
+ // Same pszName? (when no name is specified all items of the same section are removed)
+ if (StrCmpA(pamtdMsgTypes[u].pszName, pszMsgTypeName) == 0)
+ {
+ // -> Item to remove found
+
+ // Delete database setting
+ pszSetting = GetMsgTypeSettingName(pamtdMsgTypes[u].pszSection, pamtdMsgTypes[u].pszName);
+ if (pszSetting)
+ {
+ DBDeleteContactSetting(NULL, DB_MODULE_NAME_MSGTYPES, pszSetting);
+ mir_free(pszSetting);
+ }
+
+ // Free array item memory
+ if (pamtdMsgTypes[u].pszSection) mir_free(pamtdMsgTypes[u].pszSection);
+ if (pamtdMsgTypes[u].pszName) mir_free(pamtdMsgTypes[u].pszName);
+ if (pamtdMsgTypes[u].ptszSectionDescription) mir_free(pamtdMsgTypes[u].ptszSectionDescription);
+ if (pamtdMsgTypes[u].ptszDescription) mir_free(pamtdMsgTypes[u].ptszDescription);
+ if (pamtdMsgTypes[u].hIcon && ((int)pamtdMsgTypes[u].hIcon > 0)) DestroyIcon(pamtdMsgTypes[u].hIcon);
+ if (pamtdMsgTypes[u].hSectionIcon) DestroyIcon(pamtdMsgTypes[u].hSectionIcon);
+
+ // Move other array items (if not last item)
+ if ((u+1) < uMsgTypesCount)
+ MoveMemory(&pamtdMsgTypes[u], &pamtdMsgTypes[u+1], ((uMsgTypesCount-u-1)*sizeof(MESSAGETYPEDESC)));
+
+ // Resize array
+ pamtdMsgTypesBuf = (MESSAGETYPEDESC*)mir_realloc(pamtdMsgTypes, (uMsgTypesCount-1)*sizeof(MESSAGETYPEDESC));
+ if (pamtdMsgTypesBuf)
+ pamtdMsgTypes = pamtdMsgTypesBuf;
+
+ // Decrase list count
+ uMsgTypesCount--;
+
+ iReturn = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+
+ // Refresh shown list
+ if (IsWindow(hwndSpamFilterOpt))
+ SendMessage(hwndSpamFilterOpt, SFM_REBUILD_MSGTYPES, 0, 0);
+
+ return iReturn;
+}
+
+
+// Service: MS_SPAMFILTER_ISMESSAGETYPEACTIVATED
+static int ServiceIsMessageTypeActivated(WPARAM wParam, LPARAM lParam)
+{
+ int iMsgType;
+ BOOL bReturn = FALSE;
+
+ EnterCriticalSection(&csMsgTypes); // thread safety
+
+ iMsgType = GetMsgTypeID((const char*)wParam, (const char*)lParam);
+ if (iMsgType != -1)
+ if (pamtdMsgTypes[iMsgType].dwFlags&MTDF_HIDDEN)
+ {
+ bReturn = !(pamtdMsgTypes[iMsgType].dwFlags&MTDF_DEFAULTDISABLED);
+ } else {
+ char* pszSetting = GetMsgTypeSettingName(pamtdMsgTypes[iMsgType].pszSection, pamtdMsgTypes[iMsgType].pszName);
+ if (pszSetting)
+ {
+ bReturn = DBGetContactSettingByte(NULL, DB_MODULE_NAME_MSGTYPES, pszSetting, (BYTE)!(pamtdMsgTypes[iMsgType].dwFlags&MTDF_DEFAULTDISABLED));
+ mir_free(pszSetting);
+ }
+ }
+
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return (int)bReturn;
+}
+
+
+// Service: MS_SPAMFILTER_ROBOTCHECK
+static int ServiceRobotCheck(WPARAM wParam, LPARAM lParam) // wParam = SPAMCHECKDATA, lParam = 0
+{
+ SPAMCHECKDATA* pscd = (SPAMCHECKDATA*)wParam;
+
+ if (!pscd || !pscd->pszMsgTypeSection || !pscd->pszMsgTypeName || (pscd->cbSize < sizeof(SPAMCHECKDATA)) || !SCD_IsUserValid(pscd))
+ return SFF_ISNORMAL;
+
+ // Check id ctrl key is pressed to manually cancel spam check
+ if (!(pscd->dwFlags&SCDF_NO_CANCEL) && (GetAsyncKeyState(VK_CONTROL)&0x8000))
+ return SFF_ISNORMAL;
+
+ if ( !CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)pscd->pszMsgTypeSection, (LPARAM)pscd->pszMsgTypeName)
+ || !CallService(MS_SPAMFILTER_GETSPAMCHECKINFO, (WPARAM)SFSCI_ACTIVATION_FILTER, (LPARAM)SFT_ROBOT_FILTER) )
+ return SFF_ISNORMAL;
+
+ if (NotifyEventHooks(hEventOkToSpamCheck, (WPARAM)pscd, (LPARAM)SFT_ROBOT_FILTER) == 1) {
+ OutputDebugString(_T("Spam Filter: Spam check denied (by event).\r\n"));
+ return SFF_ISNORMAL;
+ }
+
+ {
+ WCHAR* pszNormalMsgText;
+ WCHAR* pszClearedMsgText = NULL;
+
+ DWORD dwReturn = SFF_ISNORMAL;
+
+ // Buffer the msg content
+ if (pscd->ptszMsgText)
+ {
+ #if defined(UNICODE)
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszNormalMsgText = pscd->ptszMsgText;
+ else
+ pszNormalMsgText = (WCHAR*)mir_utf8encodeW((WCHAR*)pscd->pszMsgText);
+ #else
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszNormalMsgText = UnicodeToAnsi(pscd->pwszMsgText);
+ else
+ pszNormalMsgText = pscd->ptszMsgText;
+ #endif
+
+ } else {
+ pszNormalMsgText = NULL;
+ }
+
+ pszClearedMsgText = mir_wstrdup(pszNormalMsgText);
+ if (pszClearedMsgText)
+ RemoveWhiteSpaces(pszClearedMsgText, FALSE, TRUE);
+ else
+ pszClearedMsgText = NULL;
+
+ if (pszClearedMsgText)
+ {
+ DBVARIANT dbv;
+
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, &dbv) == 0)
+ {
+ // If message contains correct answer
+ RemoveWhiteSpaces(dbv.ptszVal, FALSE, TRUE);
+ if ((StrCmp(pszClearedMsgText, dbv.ptszVal) == 0) || // or allow for quotes (below)
+ (StrCmpN(&pszClearedMsgText[1], dbv.ptszVal, lstrlen(pszClearedMsgText)-2) == 0))
+ dwReturn |= SFF_SENDMSG_CONFIRMATION|SFF_TESTPASSED|(DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ADDTOHISTORY, DEFAULT_SETTING_ROBOT_ADDTOHISTORY) ? SFF_MARKREAD : SFF_DELETE);
+
+ DBFreeVariant(&dbv);
+ }
+ }
+
+ if (pszClearedMsgText) mir_free(pszClearedMsgText);
+
+ #if defined(UNICODE)
+ if (!(pscd->dwFlags&SCDF_UNICODE))
+ if (pszNormalMsgText) mir_free(pszNormalMsgText);
+ #else
+ if ((pscd->dwFlags&SCDF_UNICODE))
+ if (pszNormalMsgText) mir_free(pszNormalMsgText);
+ #endif
+
+ // Kick out spam
+ if ( (!(dwReturn&SFF_TESTPASSED)) && (NotifyEventHooks(hEventOkToSpamDetection, (WPARAM)pscd, (LPARAM)SFT_ROBOT_FILTER) == 0))
+ {
+ dwReturn = SFF_ISSPAM|((DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_BEHAVIOUR, DEFAULT_SETTING_BEHAVIOUR) == 1) ? SFF_MARKREAD : SFF_DELETE);
+
+ // Add user to ignore list
+ if (!(pscd->dwFlags&SCDF_NO_AUTOIGNORE) && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_AUTOADDSPAMMERS, DEFAULT_SETTING_AUTOADDSPAMMERS) )
+ {
+ if (IncreasePreSpammerCount(pscd) > DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ALLOWEDSPAMMESSAGES, DEFAULT_SETTING_ALLOWEDSPAMMESSAGES))
+ {
+ RemovePreSpammerCount(pscd);
+ dwReturn |= SFF_IGNORE;
+ }
+ }
+
+ // Do not send question message when next messages will be ignored
+ if (!(dwReturn&SFF_IGNORE)) {
+ dwReturn |= SFF_SENDMSG_INSTRUCTION;
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_HIDEUSERS, (BYTE)DEFAULT_SETTING_ROBOT_HIDEUSERS))
+ dwReturn |= SFF_HIDE;
+ }
+
+ if (!(pscd->dwFlags&SCDF_NO_NOTIFY))
+ {
+ // Play sound file
+ SkinPlaySound(DB_SOUND_ROBOT_SETTING);
+
+ // Show Popup
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, DEFAULT_SETTING_POPUP))
+ {
+ WCHAR* pszDisplayName = SCD_GetContactCustomDisplayName(pscd);
+
+ ShowSpamPopup(pscd->pszMsgTypeSection, pscd->pszMsgTypeName, pszDisplayName, (pscd->dwFlags&SCDF_NO_CONTACT)?NULL:pscd->hContact, SFT_ROBOT_FILTER);
+ if (pszDisplayName) mir_free(pszDisplayName);
+ }
+
+ // Append to log file
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, DEFAULT_SETTING_LOGGING))
+ {
+ STRINGLIST* pslRecognition = SLNewList();
+ WCHAR* pszUserName = SCD_GetContactName(pscd, TRUE);
+
+ SLAddItem(pslRecognition, TranslateW("Robot message"));
+ WriteToLogFile(pscd->pszMsgTypeSection, pscd->pszMsgTypeName, pszUserName, pszNormalMsgText, pslRecognition, dwReturn);
+
+ if (pszUserName) mir_free(pszUserName);
+ SLFreeList(pslRecognition);
+ }
+
+ // Hand out event
+ NotifyEventHooks(hEventSpamReceived, (WPARAM)pscd, (LPARAM)SFT_ROBOT_FILTER);
+
+ // Trigger Plugin Support
+ TriggerIncomingSpam();
+ }
+
+
+ } else {
+
+ if (!(pscd->dwFlags&SCDF_NO_AUTOIGNORE))
+ RemovePreSpammerCount(pscd);
+
+ // Message is normal
+ }
+
+ return dwReturn;
+ }
+}
+
+
+// Service: MS_SPAMFILTER_DISLIKEDMESSAGECHECK
+static int ServiceDislikedMessageCheck(WPARAM wParam, LPARAM lParam) // wParam = SPAMCHECKDATA, lParam = 0
+{
+ SPAMCHECKDATA* pscd = (SPAMCHECKDATA*)wParam;
+
+ if (!pscd || !pscd->pszMsgTypeSection || !pscd->pszMsgTypeName || (pscd->cbSize < sizeof(SPAMCHECKDATA)) || !SCD_IsUserValid(pscd))
+ return SFF_ISNORMAL;
+
+ // Check id ctrl key is pressed to manually cancel spam check
+ if (!(pscd->dwFlags&SCDF_NO_CANCEL) && (GetAsyncKeyState(VK_CONTROL)&0x8000))
+ return SFF_ISNORMAL;
+
+ if ( !CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)pscd->pszMsgTypeSection, (LPARAM)pscd->pszMsgTypeName)
+ || !CallService(MS_SPAMFILTER_GETSPAMCHECKINFO, (WPARAM)SFSCI_ACTIVATION_FILTER, (LPARAM)SFT_DISLIKEDMESSAGES_FILTER) )
+ return SFF_ISNORMAL;
+
+ if (NotifyEventHooks(hEventOkToSpamCheck, (WPARAM)pscd, (LPARAM)SFT_DISLIKEDMESSAGES_FILTER) == 1) {
+ OutputDebugString(_T("Spam Filter: Spam check denied (by event).\r\n"));
+ return SFF_ISNORMAL;
+ }
+
+ {
+ BOOL bDoLog = ( (!(pscd->dwFlags&SCDF_NO_NOTIFY)) && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, DEFAULT_SETTING_LOGGING) );
+ BOOL bKickOut = FALSE;
+
+ int i;
+ WCHAR* pszNormalMsgText;
+ WCHAR* pszClearedMsgText;
+ STRINGLIST* pslRecognition = NULL;
+
+ // Create recognition texts list
+ if (bDoLog) pslRecognition = SLNewList();
+
+ // Buffer the msg content
+ if (pscd->pszMsgText)
+ {
+ #if defined(UNICODE)
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszNormalMsgText = pscd->ptszMsgText;
+ else
+ pszNormalMsgText = (WCHAR*)mir_utf8encodeW((WCHAR*)pscd->pszMsgText);
+ #else
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszNormalMsgText = UnicodeToAnsi(pscd->pwszMsgText);
+ else
+ pszNormalMsgText = pscd->ptszMsgText;
+ #endif
+
+ pszClearedMsgText = mir_wstrdup(pszNormalMsgText);
+ if (pszClearedMsgText)
+ RemoveWhiteSpaces(pszClearedMsgText, TRUE, TRUE);
+
+ } else {
+ pszNormalMsgText = NULL;
+ pszClearedMsgText = NULL;
+ }
+
+ // -SPAMCHECKS-
+
+ // Customized indicating words
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_CUSTOMIZEDWORDS, (BYTE)TRUE))
+ {
+ STRINGLIST* pslChainWords = SLNewList();
+ unsigned int uFoundChainWords = 0;
+
+ GetSpamDefinitionData(pslChainWords, SDID_CUSTOM_DISLIKEDWORDS);
+
+ // Check how many words exist in the message
+ for (i=0; i<=SLGetMaxPos(pslChainWords); i++)
+ if (RegExpExistsInString(pszClearedMsgText, SLGetItem(pslChainWords, i), FALSE, NULL))
+ uFoundChainWords++;
+
+ SLFreeList(pslChainWords);
+
+ if (uFoundChainWords > 0)
+ {
+ if (bDoLog) SLItemPrintf(pslRecognition, SLAddItem(pslRecognition, TranslateW("Contains %u disliked indicating phrase(s)/pattern(s)")), MAX_INT_LENGTH, uFoundChainWords);
+ bKickOut = TRUE;
+ if (!bDoLog) goto DislikedMessageResult;
+ }
+ }
+
+
+ // Multiple message check
+ if (pszNormalMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_MULTIPLEMESSAGES, DEFAULT_SETTING_DISLIKEDMESSAGE_MULTIPLEMESSAGES))
+ {
+ DBVARIANT dbv;
+ BOOL bFound;
+ WCHAR* pszSender;
+
+ pszSender = SCD_GetContactUniqueStr(pscd, FALSE);
+
+ bFound = FALSE;
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_LASTMESSAGE, &dbv) == 0)
+ {
+ if (StrCmp(pszNormalMsgText, dbv.ptszVal) == 0)
+ {
+ DBFreeVariant(&dbv);
+
+ if (pszSender)
+ {
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_LASTSENDER, &dbv) == 0)
+ if (StrCmp(pszSender, dbv.ptszVal) == 0)
+ bFound = TRUE;
+
+ } else {
+ bFound = TRUE;
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ // Always save current msg content
+ DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_LASTMESSAGE, pszNormalMsgText);
+ if (pszSender)
+ DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_LASTSENDER, pszSender);
+ else
+ DBDeleteContactSetting(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_LASTSENDER);
+
+ if (pszSender) mir_free(pszSender);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Is multiple"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto DislikedMessageResult;
+ }
+
+ } else if (!pszNormalMsgText) {
+ DBDeleteContactSetting(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_LASTMESSAGE);
+ }
+
+
+ // Default hoax texts
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_HOAXTEXTS, DEFAULT_SETTING_DISLIKEDMESSAGE_HOAXTEXTS))
+ {
+ STRINGLIST* pslHoaxTexts = SLNewList();
+ BOOL bFound;
+
+ // Load hoax texts
+ GetSpamDefinitionData(pslHoaxTexts, SDID_HOAXTEXTS);
+
+ bFound = FALSE;
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(pslHoaxTexts); i++)
+ if (StrCmpI(pszClearedMsgText, SLGetItem(pslHoaxTexts, i)) == 0)
+ {
+ bFound = TRUE;
+ break;
+ }
+
+ SLFreeList(pslHoaxTexts);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Is hoax text"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto DislikedMessageResult;
+ }
+ }
+
+
+DislikedMessageResult:
+
+ if (pszClearedMsgText) mir_free(pszClearedMsgText);
+
+ #if defined(UNICODE)
+ if (!(pscd->dwFlags&SCDF_UNICODE) && pszNormalMsgText)
+ if (pszNormalMsgText) mir_free(pszNormalMsgText);
+ #else
+ if ((pscd->dwFlags&SCDF_UNICODE) && pszNormalMsgText)
+ mir_free(pszNormalMsgText);
+ #endif
+
+ // Kick out spam
+ if ( bKickOut && (NotifyEventHooks(hEventOkToSpamDetection, (WPARAM)pscd, (LPARAM)SFT_DISLIKEDMESSAGES_FILTER) == 0))
+ {
+ DWORD dwReturn = SFF_ISSPAM|((DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_BEHAVIOUR, DEFAULT_SETTING_BEHAVIOUR) == 1) ? SFF_MARKREAD : SFF_DELETE);
+
+ // Add user to ignore list
+ if (!(pscd->dwFlags&SCDF_NO_AUTOIGNORE) && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_AUTOADDSPAMMERS, DEFAULT_SETTING_AUTOADDSPAMMERS) )
+ {
+ if (IncreasePreSpammerCount(pscd) > DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ALLOWEDSPAMMESSAGES, DEFAULT_SETTING_ALLOWEDSPAMMESSAGES))
+ {
+ RemovePreSpammerCount(pscd);
+ dwReturn |= SFF_IGNORE;
+ }
+ }
+
+ // Reply to sender
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_NOTIFYSENDER, DEFAULT_SETTING_DISLIKEDMESSAGE_NOTIFYSENDER))
+ dwReturn |= SFF_SENDMSG_NOTIFY;
+
+ if (!(pscd->dwFlags&SCDF_NO_NOTIFY))
+ {
+ // Play sound file
+ SkinPlaySound(DB_SOUND_DISLIKEDMESSAGE_SETTING);
+
+ // Show Popup
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, DEFAULT_SETTING_POPUP))
+ {
+ WCHAR* pszDisplayName = SCD_GetContactCustomDisplayName(pscd);
+ ShowSpamPopup(pscd->pszMsgTypeSection, pscd->pszMsgTypeName, pszDisplayName, (pscd->dwFlags&SCDF_NO_CONTACT)?NULL:pscd->hContact, SFT_DISLIKEDMESSAGES_FILTER);
+ if (pszDisplayName) mir_free(pszDisplayName);
+ }
+
+ // Hand out event
+ NotifyEventHooks(hEventSpamReceived, (WPARAM)pscd, (LPARAM)SFT_DISLIKEDMESSAGES_FILTER);
+
+ // Trigger Plugin Support
+ TriggerIncomingSpam();
+ }
+
+ // Append to log file
+ if (bDoLog)
+ {
+ WCHAR* pszUserName = SCD_GetContactName(pscd, TRUE);
+
+ WriteToLogFile(pscd->pszMsgTypeSection, pscd->pszMsgTypeName, pszUserName, pszNormalMsgText, pslRecognition, dwReturn);
+ if (pszUserName) mir_free(pszUserName);
+
+ SLFreeList(pslRecognition);
+ }
+
+ return dwReturn;
+
+ } else {
+
+ if (bDoLog)
+ SLFreeList(pslRecognition);
+
+ if (!(pscd->dwFlags&SCDF_NO_AUTOIGNORE))
+ RemovePreSpammerCount(pscd); // count can be removed here
+
+ // Message is normal
+ return SFF_ISNORMAL;
+ }
+
+ }
+}
+
+
+// Service : MS_SPAMFILTER_ADVERTISMENTCHECK
+static int ServiceAdvertismentCheck(WPARAM wParam, LPARAM lParam) // wParam = SPAMCHECKDATA, lParam = 0
+{
+ SPAMCHECKDATA* pscd = (SPAMCHECKDATA*)wParam;
+
+ if (!pscd || !pscd->pszMsgTypeSection || !pscd->pszMsgTypeName || (pscd->cbSize < sizeof(SPAMCHECKDATA)) || !SCD_IsUserValid(pscd))
+ return SFF_ISNORMAL;
+
+ // Check id ctrl key is pressed to manually cancel spam check
+ if (!(pscd->dwFlags&SCDF_NO_CANCEL) && (GetAsyncKeyState(VK_CONTROL)&0x8000))
+ return SFF_ISNORMAL;
+
+ if ( !CallService(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, (WPARAM)pscd->pszMsgTypeSection, (LPARAM)pscd->pszMsgTypeName)
+ || !CallService(MS_SPAMFILTER_GETSPAMCHECKINFO, (WPARAM)SFSCI_ACTIVATION_FILTER, (LPARAM)SFT_ADVERTISMENT_FILTER) )
+ return SFF_ISNORMAL;
+
+ if (NotifyEventHooks(hEventOkToSpamCheck, (WPARAM)pscd, (LPARAM)SFT_ADVERTISMENT_FILTER) == 1) {
+ OutputDebugString(_T("Spam Filter: Spam check denied (by event).\r\n"));
+ return SFF_ISNORMAL;
+ }
+
+ {
+ BOOL bDoLog = ( (!(pscd->dwFlags&SCDF_NO_NOTIFY)) && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, DEFAULT_SETTING_LOGGING) );
+ BOOL bIsKnownSpammer = FALSE;
+ BOOL bKickOut = FALSE;
+ BOOL bFound;
+
+ int i;
+ WCHAR* pszNormalMsgText;
+ WCHAR* pszClearedMsgText;
+ WCHAR* pszFormatedMsgText;
+ STRINGLIST* pslRecognition = NULL;
+
+ // Create recognition texts list
+ if (bDoLog) pslRecognition = SLNewList();
+
+ // Buffer the msg content
+ if (pscd->pszMsgText)
+ {
+ #if defined(UNICODE)
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszNormalMsgText = pscd->ptszMsgText;
+ else
+ pszNormalMsgText = (WCHAR*)mir_utf8encodeW((WCHAR*)pscd->pszMsgText);
+ #else
+ if (pscd->dwFlags&SCDF_UNICODE)
+ pszNormalMsgText = UnicodeToAnsi(pscd->pwszMsgText);
+ else
+ pszNormalMsgText = pscd->ptszMsgText;
+ #endif
+
+ pszClearedMsgText = mir_wstrdup(pszNormalMsgText);
+ if (pszClearedMsgText)
+ RemoveWhiteSpaces(pszClearedMsgText, TRUE, TRUE);
+
+ } else {
+ pszNormalMsgText = NULL;
+ pszClearedMsgText = NULL;
+ }
+
+ // Create different format check text
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_FORMATING, DEFAULT_SETTING_ADVERTISMENT_FORMATING))
+ {
+ pszFormatedMsgText = mir_wstrdup(pszClearedMsgText);
+ if (pszFormatedMsgText)
+ {
+ STRINGLIST* pslFormat = SLNewList();
+
+ // Some words may have special chars in between the chars
+ GetSpamDefinitionData(pslFormat, SDID_SPECIALCHARS_SEPARATORS);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(pslFormat); i++)
+ ReplaceSubStringWithStringBuf(pszFormatedMsgText, 0, SLGetItem(pslFormat, i), _T(" "), TRUE, FALSE);
+
+ SLClearList(pslFormat);
+
+ // Translate some chars
+ GetSpamDefinitionData(pslFormat, SDID_SPECIALCHARS_REPLACE_TEXT);
+ ReplaceSubStringWithStringMultipleBuf(pszFormatedMsgText, 0, pslFormat, TRUE, FALSE);
+
+ SLFreeList(pslFormat);
+ }
+ } else {
+ pszFormatedMsgText = NULL;
+ }
+
+ // -SPAMCHECKS-
+ // Multiple message check
+ if (pszNormalMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_MULTIPLEMESSAGES, DEFAULT_SETTING_ADVERTISMENT_MULTIPLEMESSAGES))
+ {
+ DBVARIANT dbv;
+ bFound = FALSE;
+
+ // Do not consider sender of NotOnList messages
+ if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_LASTMESSAGE, &dbv) == 0)
+ {
+ if (StrCmp(pszNormalMsgText, dbv.ptszVal) == 0)
+ bFound = TRUE;
+
+ DBFreeVariant(&dbv);
+ }
+
+ // Always save current msg content
+ DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_LASTMESSAGE, pszNormalMsgText);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Is multiple"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+
+ } else if (!pszNormalMsgText) {
+ DBDeleteContactSetting(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_LASTMESSAGE);
+ }
+
+ // Empty message?
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_EMPTY, DEFAULT_SETTING_ADVERTISMENT_EMPTY))
+ {
+ if (lstrlen(pszClearedMsgText) <= 0)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Is empty"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+ // Message capitalized?
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CAPITALIZED, DEFAULT_SETTING_ADVERTISMENT_CAPITALIZED))
+ {
+ bFound = TRUE;
+
+ for (i=0; i<(int)lstrlen(pszClearedMsgText); i++)
+ if (IsCharLower(pszClearedMsgText[i]))
+ {
+ bFound = FALSE;
+ break;
+ }
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Is capitalized"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+ // Sender is default spammer?
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTSPAMMERS, DEFAULT_SETTING_ADVERTISMENT_DEFAULTSPAMMERS))
+ {
+ STRINGLIST* psl = SLNewList();
+ WCHAR* pszUnique;
+
+ // Load spammers definitions
+ GetSpamDefinitionData(psl, SDID_SPAMMERS);
+
+ // Check if unique user id is listed in def file
+ pszUnique = SCD_GetContactUniqueStr(pscd, FALSE);
+ if (pszUnique)
+ {
+ bFound = SLIsItem(psl, pszUnique, TRUE);
+ mir_free(pszUnique);
+ } else {
+ bFound = FALSE;
+ }
+
+ // Check if nickname is listed in def file
+ if (!bFound)
+ {
+ pszUnique = SCD_GetContactUniqueStr(pscd, TRUE);
+ if (pszUnique)
+ {
+ bFound = SLIsItem(psl, pszUnique, TRUE);
+ mir_free(pszUnique);
+ }
+ }
+ SLFreeList(psl);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("User is known as spammer"));
+ bKickOut = bIsKnownSpammer = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+ // Teaser Message?
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_TEASERMESSAGES, DEFAULT_SETTING_ADVERTISMENT_TEASERMESSAGES))
+ {
+ STRINGLIST* pslTeasers = SLNewList();
+ bFound = FALSE;
+
+ // Load teasers
+ GetSpamDefinitionData(pslTeasers, SDID_TEASERTEXTS);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(pslTeasers); i++)
+ if (StrCmp(pszClearedMsgText, SLGetItem(pslTeasers, i)) == 0)
+ {
+ bFound = TRUE;
+ break;
+ }
+
+ SLFreeList(pslTeasers);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Is teaser"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+ // Message containing URLs?
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_URL, DEFAULT_SETTING_ADVERTISMENT_URL))
+ {
+ STRINGLIST* psl = SLNewList();
+ WCHAR* pszModUrlInd = NULL;
+ bFound = FALSE;
+
+ // Load url definition files
+ GetSpamDefinitionData(psl, SDID_URLTLDS);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ {
+ // Different formated check?
+ if (pszFormatedMsgText)
+ pszModUrlInd = InsertSubStrEveryNChars(SLGetItem(psl, i), 1, _T(" "), FALSE, FALSE); // check for words with spaces/linefeeds/slashes between each char
+
+ if (StrStrI(pszClearedMsgText, SLGetItem(psl, i)) || ((pszModUrlInd && pszFormatedMsgText) ? StrStrI(pszFormatedMsgText, pszModUrlInd) : FALSE) )
+ {
+ bFound = TRUE;
+ break;
+ }
+
+ if (pszModUrlInd)
+ {
+ mir_free(pszModUrlInd);
+ pszModUrlInd = NULL;
+ }
+ }
+
+ SLFreeList(psl);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Contains URL address"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+ // Message containing phone numbers?
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_PHONENUMBERS, DEFAULT_SETTING_ADVERTISMENT_PHONENUMBERS))
+ {
+ STRINGLIST* psl = SLNewList();
+ WCHAR* pszModContent;
+ bFound = FALSE;
+
+ // Load localized phonenumbers
+ GetSpamDefinitionData(psl, SDID_PHONENUMBERS);
+
+ pszModContent = mir_wstrdup(pszClearedMsgText);
+ if (pszModContent)
+ {
+ // Check for normal formated phonennumbers
+ {
+ // Remove spaces
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T(" "), NULL, TRUE, FALSE);
+ // Replace wrong slashs
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("\\"), _T("/"), TRUE, FALSE);
+
+ // Replace numbers
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("0"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("1"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("2"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("3"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("4"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("5"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("6"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("7"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("8"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("9"), _T("#"), TRUE, FALSE);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ if (StrStrI(pszModContent, SLGetItem(psl, i)))
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+
+ // Check different formated phone numbers
+ if (!bFound && pszFormatedMsgText)
+ {
+ WCHAR* pszNumberFormatedMsgText = mir_wstrdup(pszClearedMsgText);
+ if (pszNumberFormatedMsgText)
+ {
+ // -- Create number formated text
+ STRINGLIST* pslFormat = SLNewList();
+
+ // Some words may have special chars in between the chars
+ GetSpamDefinitionData(pslFormat, SDID_SPECIALCHARS_SEPARATORS);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(pslFormat); i++)
+ ReplaceSubStringWithStringBuf(pszNumberFormatedMsgText, 0, SLGetItem(pslFormat, i), _T(" "), TRUE, FALSE);
+
+ SLClearList(pslFormat);
+
+ // Translate some chars
+ GetSpamDefinitionData(pslFormat, SDID_SPECIALCHARS_REPLACE_NUMBERS);
+ ReplaceSubStringWithStringMultipleBuf(pszNumberFormatedMsgText, 0, pslFormat, TRUE, FALSE);
+
+ SLFreeList(pslFormat);
+
+
+ //-- Check the text
+ // Remove spaces
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T(" "), NULL, TRUE, FALSE);
+ // Replace wrong slashs
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("\\"), _T("/"), TRUE, FALSE);
+
+ // Replace numbers
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("0"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("1"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("2"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("3"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("4"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("5"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("6"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("7"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("8"), _T("#"), TRUE, FALSE);
+ ReplaceSubStringWithStringBuf(pszModContent, 0, _T("9"), _T("#"), TRUE, FALSE);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ if (StrStrI(pszModContent, SLGetItem(psl, i)))
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+ }
+
+ mir_free(pszModContent);
+ }
+
+ SLFreeList(psl);
+
+ if (bFound)
+ {
+ if (bDoLog) SLAddItem(pslRecognition, TranslateW("Contains phone number"));
+ bKickOut = TRUE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+ // Message contains bad words and/or formated bad words?
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDBADWORDS, (BYTE)TRUE) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTBADWORDS, DEFAULT_SETTING_ADVERTISMENT_DEFAULTBADWORDS) )
+ {
+ STRINGLIST* psl = SLNewList();
+ unsigned int uFoundBadWords = 0;
+ unsigned int uFoundFormatedWords = 0;
+ BOOL bRegExpMalformed;
+ unsigned int uRegExpErrors;
+
+ // Load cutomized bad words if activated
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDBADWORDS, (BYTE)TRUE) )
+ GetSpamDefinitionData(psl, SDID_CUSTOM_BADWORDS);
+
+ // Check customized bad words...
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ if (RegExpExistsInString(pszClearedMsgText, SLGetItem(psl, i), FALSE, NULL))
+ uFoundBadWords++;
+
+ // Load all default bad words files if activated
+ SLClearList(psl);
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTBADWORDS, DEFAULT_SETTING_ADVERTISMENT_DEFAULTBADWORDS) )
+ GetSpamDefinitionData(psl, SDID_BADWORDS);
+
+ // Check default bad words...
+ uRegExpErrors = 0;
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ {
+ if (RegExpExistsInString(pszClearedMsgText, SLGetItem(psl, i), FALSE, &bRegExpMalformed))
+ uFoundBadWords++;
+
+ if (bRegExpMalformed)
+ uRegExpErrors++;
+ }
+ if (uRegExpErrors > 0)
+ ShowInfoMessage(NIIF_WARNING, TranslateW("Spam Filter Warning"), TranslateW("The filter has detected %u malformed Regular Expression(s) in the default bad words!\r\n\r\nPlease update your installed Spam Definitions to the latest versions to resolve this problem.\r\nThis problem might also be caused by Spam Definitions that are not compatible with your system codepage."), MAX_INT_LENGTH, uRegExpErrors);
+
+ // Check different formated bad words...
+ if (pszFormatedMsgText)
+ {
+ WCHAR* pszDiffWord;
+
+ // AGAIN!: Load cutomized bad words again if activated
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDBADWORDS, (BYTE)TRUE) )
+ GetSpamDefinitionData(psl, SDID_CUSTOM_BADWORDS);
+
+ // Check again for bad words
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ {
+ pszDiffWord = InsertSubStrEveryNChars(SLGetItem(psl, i), 1, _T(" "), FALSE, FALSE); // check for words with spaces/linefeeds between each char
+
+ if (RegExpExistsInString(pszFormatedMsgText, SLGetItem(psl, i), FALSE, NULL))
+ {
+ uFoundFormatedWords++;
+
+ } else {
+ pszDiffWord = InsertSubStrEveryNChars(SLGetItem(psl, i), 1, _T(" "), FALSE, FALSE); // check for words with spaces/linefeeds between each char
+ if (pszDiffWord)
+ {
+ if (StrStrI(pszFormatedMsgText, pszDiffWord))
+ uFoundFormatedWords++;
+
+ mir_free(pszDiffWord);
+ }
+ }
+ }
+
+ // Calculate diff
+ uFoundFormatedWords = (uFoundFormatedWords > uFoundBadWords) ? uFoundFormatedWords = uFoundFormatedWords-uFoundBadWords : 0;
+ }
+
+ SLFreeList(psl);
+
+ // Enough bad words for spam found?
+ if (uFoundBadWords > DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDBADWORDS, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDBADWORDS))
+ {
+ if (bDoLog) SLItemPrintf(pslRecognition, SLAddItem(pslRecognition, TranslateW("Contains %u bad phrase(s)/pattern(s)")) , MAX_INT_LENGTH, uFoundBadWords);
+ bKickOut = TRUE;
+ }
+
+ // Enough formated bad words found?
+ if (uFoundFormatedWords > DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDFORMATEDWORDS, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDFORMATEDWORDS))
+ {
+ if (bDoLog) SLItemPrintf(pslRecognition, SLAddItem(pslRecognition, TranslateW("Contains %u differently formated bad phrase(s)/pattern(s)")), MAX_INT_LENGTH, uFoundFormatedWords);
+ bKickOut = TRUE;
+ }
+
+ if (bKickOut && !bDoLog) goto AdvertismentResult;
+ }
+
+ // Good words check
+ if (pszClearedMsgText && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDGOODWORDS, (BYTE)TRUE) )
+ {
+ STRINGLIST* psl = SLNewList();
+ unsigned int uFoundGoodWords = 0;
+
+ // Load customized good words
+ GetSpamDefinitionData(psl, SDID_CUSTOM_GOODWORDS);
+
+ for (i=SL_MIN_POS; i<=SLGetMaxPos(psl); i++)
+ if (RegExpExistsInString(pszClearedMsgText, SLGetItem(psl, i), FALSE, NULL))
+ uFoundGoodWords++;
+
+ SLFreeList(psl);
+
+ // Enough good words for non-spam found?
+ if (uFoundGoodWords > DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS))
+ {
+ if (bDoLog) SLItemPrintf(pslRecognition, SLAddItem(pslRecognition, TranslateW("Contains %u good phrase(s)/pattern(s)")), MAX_INT_LENGTH, uFoundGoodWords);
+ bKickOut = FALSE;
+ if (!bDoLog) goto AdvertismentResult;
+ }
+ }
+
+
+AdvertismentResult:
+
+ if (pszClearedMsgText) mir_free(pszClearedMsgText);
+ if (pszFormatedMsgText) mir_free(pszFormatedMsgText);
+
+ #if defined(UNICODE)
+ if (!(pscd->dwFlags&SCDF_UNICODE) && pszNormalMsgText)
+ mir_free(pszNormalMsgText);
+ #else
+ if ((pscd->dwFlags&SCDF_UNICODE) && pszNormalMsgText)
+ mir_free(pszNormalMsgText);
+ #endif
+
+
+ // Kick out spam
+ if ( bKickOut && (NotifyEventHooks(hEventOkToSpamDetection, (WPARAM)pscd, (LPARAM)SFT_ADVERTISMENT_FILTER) == 0))
+ {
+ DWORD dwReturn = SFF_ISSPAM | ((DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_BEHAVIOUR, DEFAULT_SETTING_BEHAVIOUR) == 1) ? SFF_MARKREAD : SFF_DELETE);
+
+ if (!(pscd->dwFlags&SCDF_NO_NOTIFY))
+ {
+ // Play sound file
+ SkinPlaySound(DB_SOUND_ADVERTISMENT_SETTING);
+
+ // Show Popup
+ if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, DEFAULT_SETTING_POPUP))
+ {
+ WCHAR* pszDisplayName = SCD_GetContactCustomDisplayName(pscd);
+
+ ShowSpamPopup(pscd->pszMsgTypeSection, pscd->pszMsgTypeName, pszDisplayName, (pscd->dwFlags&SCDF_NO_CONTACT)?NULL:pscd->hContact, SFT_ADVERTISMENT_FILTER);
+ if (pszDisplayName) mir_free(pszDisplayName);
+ }
+
+ // Hand out event
+ NotifyEventHooks(hEventSpamReceived, (WPARAM)pscd, (LPARAM)SFT_ADVERTISMENT_FILTER);
+
+ // Trigger Plugin Support
+ TriggerIncomingSpam();
+ }
+
+ // Append to log file
+ if (bDoLog)
+ {
+ WCHAR* pszUserName = SCD_GetContactName(pscd, TRUE);
+
+ WriteToLogFile(pscd->pszMsgTypeSection, pscd->pszMsgTypeName, pszUserName, pszNormalMsgText, pslRecognition, dwReturn);
+ if (pszUserName) mir_free(pszUserName);
+
+ SLFreeList(pslRecognition);
+ }
+
+ // Add user to ignore list
+ if (!(pscd->dwFlags&SCDF_NO_AUTOIGNORE) && DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_AUTOADDSPAMMERS, DEFAULT_SETTING_AUTOADDSPAMMERS) )
+ {
+ if (IncreasePreSpammerCount(pscd) > DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ALLOWEDSPAMMESSAGES, DEFAULT_SETTING_ALLOWEDSPAMMESSAGES))
+ {
+ RemovePreSpammerCount(pscd);
+ dwReturn |= SFF_IGNORE;
+ }
+ }
+
+ return dwReturn;
+
+ } else {
+
+ if (bDoLog)
+ SLFreeList(pslRecognition);
+
+ //if (!(pscd->dwFlags&SCDF_NO_AUTOIGNORE))
+ // RemovePreSpammerCount(scd); // do not remove count here! (will cause problems)
+
+ // Message is normal
+ return SFF_ISNORMAL;
+ }
+
+ }
+}
+
+
+// --------------------------------
+
+int GetMsgTypeID(const char* pszSection, const char* pszName)
+{
+ unsigned int u;
+
+ EnterCriticalSection(&csMsgTypes); // thread safety
+
+ if (pszSection && pszName && pamtdMsgTypes)
+ for (u=0; u<uMsgTypesCount; u++)
+ if (StrCmpA(pamtdMsgTypes[u].pszSection, pszSection) == 0)
+ if (StrCmpA(pamtdMsgTypes[u].pszName, pszName) == 0)
+ {
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return u;
+ }
+
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return -1;
+}
+
+
+char* GetMsgTypeSettingName(const char* pszSection, const char* pszName)
+{
+ // returned char* needs to be freed
+ char* pszReturn;
+ int iSize;
+
+ if (!pszSection || !pszName) return NULL;
+
+ iSize = lstrlenA(pszSection)+1+lstrlenA(pszName)+1;
+ pszReturn = (char*)mir_alloc(iSize*sizeof(char));
+
+ if (pszReturn)
+ mir_snprintf(pszReturn, iSize, "%s_%s", pszSection, pszName);
+
+ return pszReturn;
+}
+
+
+BOOL IsOnlyOneMsgTypeSectionRegistered(void)
+{
+ unsigned int u;
+
+ EnterCriticalSection(&csMsgTypes); // thread safety
+
+ if (pamtdMsgTypes)
+ for (u=0; u<(uMsgTypesCount-1); u++)
+ if (StrCmpA(pamtdMsgTypes[u].pszSection, pamtdMsgTypes[u+1].pszSection) != 0)
+ {
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return FALSE;
+ }
+
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ return TRUE;
+}
+
+
+void NotifyModuleLoaded(void)
+{
+ // Hand out event (spam filter functionality now fully available)
+ NotifyEventHooks(hEventModuleLoaded, 0, 0);
+}
+
+void NotifySpammerStateChanged(HANDLE hContact, BOOL bNewIsSpammer)
+{
+ // Hand out event (spammer state setting was changed)
+ NotifyEventHooks(hEventContactSpammerStateChanged, (WPARAM)hContact, (LPARAM)bNewIsSpammer);
+}
+
+// --------------------------------
+
+
+void InitServices(void)
+{
+ // Init message type list
+ uMsgTypesCount = 0;
+ pamtdMsgTypes = NULL;
+ InitializeCriticalSection(&csMsgTypes); // thread safety
+
+ hEventPreRegisterMessageType = CreateHookableEvent(ME_SPAMFILTER_PREREGISTERMESSAGETYPE);
+ hEventOkToSpamCheck = CreateHookableEvent(ME_SPAMFILTER_OKTOSPAMCHECK);
+ hEventOkToSpamDetection = CreateHookableEvent(ME_SPAMFILTER_OKTOSPAMDETECTION);
+ hEventSpamReceived = CreateHookableEvent(ME_SPAMFILTER_SPAMRECEIVED);
+ hEventModuleLoaded = CreateHookableEvent(ME_SPAMFILTER_MODULELOADED);
+ hEventContactSpammerStateChanged = CreateHookableEvent(ME_SPAMFILTER_CONTACT_SPAMMERSTATECHANGED);
+
+ hServices[0] = CreateServiceFunction(MS_SPAMFILTER_ADVERTISMENTCHECK, ServiceAdvertismentCheck);
+ hServices[1] = CreateServiceFunction(MS_SPAMFILTER_DISLIKEDMESSAGESCHECK, ServiceDislikedMessageCheck);
+ hServices[2] = CreateServiceFunction(MS_SPAMFILTER_ROBOTCHECK, ServiceRobotCheck);
+
+ hServices[3] = CreateServiceFunction(MS_SPAMFILTER_REGISTERMESSAGETYPE, ServiceRegisterMessageType);
+ hServices[4] = CreateServiceFunction(MS_SPAMFILTER_REMOVEMESSAGETYPE, ServiceRemoveMessageType);
+ hServices[5] = CreateServiceFunction(MS_SPAMFILTER_ISMESSAGETYPEACTIVATED, ServiceIsMessageTypeActivated);
+
+ hServices[6] = CreateServiceFunction(MS_SPAMFILTER_GETHANDLE, ServiceGetHandle);
+ hServices[7] = CreateServiceFunction(MS_SPAMFILTER_SHOWERROR, ServiceShowError);
+ hServices[8] = CreateServiceFunction(MS_SPAMFILTER_SHOWFILTERDIALOG, ServiceShowFilterDialog);
+
+ hServices[9] = CreateServiceFunction(MS_SPAMFILTER_CHANGEFILTERACTIVATION, ServiceChangeFilterActivation);
+ hServices[10] = CreateServiceFunction(MS_SPAMFILTER_GETSPAMCHECKINFO, ServiceGetSpamCheckInfo);
+
+ hServices[11] = CreateServiceFunction(MS_SPAMFILTER_RESETAUTOIGNORE, ServiceResetAutoIgnore);
+
+ hServices[12] = CreateServiceFunction(MS_SPAMFILTER_CONTACT_SETASSPAMMER, ServiceContactSetAsSpammer);
+ hServices[13] = CreateServiceFunction(MS_SPAMFILTER_CONTACT_SHOWSETASSPAMMERDIALOG, ServiceContactShowSetAsSpammerDialog);
+ hServices[14] = CreateServiceFunction(MS_SPAMFILTER_CONTACT_ISSPAMMER, ServiceContactIsSpammer);
+ hServices[15] = CreateServiceFunction(MS_SPAMFILTER_CONTACT_UNSETSPAMMER, ServiceContactUnSetSpammer);
+
+ hServices[16] = CreateServiceFunction(MS_SPAMFILTER_COPYSPAMCHECKDATA, ServiceCopySpamCheckData);
+ hServices[17] = CreateServiceFunction(MS_SPAMFILTER_FREESPAMCHECKDATA, ServiceFreeSpamCheckData);
+
+ // Backward compatibility (for v1.0.1.0)
+ hServices[18] = CreateServiceFunction(MS_SPAMFILTER_SETSPAMMANUALLY, ServiceContactShowSetAsSpammerDialog);
+}
+
+void UninitServices(void)
+{
+ // Destroy services
+ int i;
+ for (i=0; i<ARRAYSIZE(hServices); i++)
+ if (hServices[i]) DestroyServiceFunction(hServices[i]);
+
+ if (hEventPreRegisterMessageType)
+ DestroyHookableEvent(hEventPreRegisterMessageType);
+ if (hEventOkToSpamCheck)
+ DestroyHookableEvent(hEventOkToSpamCheck);
+ if (hEventOkToSpamDetection)
+ DestroyHookableEvent(hEventOkToSpamDetection);
+ if (hEventSpamReceived)
+ DestroyHookableEvent(hEventSpamReceived);
+ if (hEventModuleLoaded)
+ DestroyHookableEvent(hEventModuleLoaded);
+ if (hEventContactSpammerStateChanged)
+ DestroyHookableEvent(hEventContactSpammerStateChanged);
+
+ // Unload message type list
+ EnterCriticalSection(&csMsgTypes); // thread safety (waiting for operations to fisnish)
+ if (pamtdMsgTypes)
+ {
+ unsigned int u;
+ for (u=0; u<uMsgTypesCount; u++)
+ {
+ if (pamtdMsgTypes[u].pszSection) mir_free(pamtdMsgTypes[u].pszSection);
+ if (pamtdMsgTypes[u].pszSectionDescription) mir_free(pamtdMsgTypes[u].pszSectionDescription);
+ if (pamtdMsgTypes[u].pszName) mir_free(pamtdMsgTypes[u].pszName);
+ if (pamtdMsgTypes[u].pszDescription) mir_free(pamtdMsgTypes[u].pszDescription);
+ if (pamtdMsgTypes[u].hIcon && ((int)pamtdMsgTypes[u].hIcon > 0)) DestroyIcon(pamtdMsgTypes[u].hIcon);
+ if (pamtdMsgTypes[u].hSectionIcon) DestroyIcon(pamtdMsgTypes[u].hSectionIcon);
+ }
+ mir_free(pamtdMsgTypes);
+ }
+ uMsgTypesCount = 0;
+ pamtdMsgTypes = NULL;
+ LeaveCriticalSection(&csMsgTypes); // thread safety
+ DeleteCriticalSection(&csMsgTypes); // thread safety
+} \ No newline at end of file