static int OnFastDump(WPARAM wParam,LPARAM lParam) { if ( pActive ) { LOGMSG *logMsg = (LOGMSG*)lParam; DWORD headlen = (DWORD)strlen(logMsg->pszHead); DWORD msglen = (DWORD)strlen(logMsg->pszMsg); DWORD len = (headlen + msglen + 1) * sizeof(TCHAR) + sizeof(DUMPMSG); DUMPMSG *dumpMsg = (DUMPMSG*)mir_alloc( len ); TCHAR *str = dumpMsg->szMsg; char *szModule = (wParam) ? ((NETLIBUSER*)wParam)->szDescriptiveName : "[Core]"; strncpy_s(dumpMsg->szModule, SIZEOF(dumpMsg->szModule), szModule, _TRUNCATE); wchar_t *ucs2 = mir_a2u(logMsg->pszHead); wcscpy(str, ucs2); mir_free(ucs2); // try to detect utf8 ucs2 = mir_utf8decodeW(logMsg->pszMsg); if ( !ucs2 ) ucs2 = mir_a2u(logMsg->pszMsg); wcscat(str, ucs2); mir_free(ucs2); InMsgs++; PostMessage(hwndConsole, HM_DUMP, 0, (LPARAM)dumpMsg); } return 0; }
LPSTR TranslateU( LPCSTR lpText ) { int i; for(i=0;i<ca2u;i++) { if( pa2u[i].a == lpText ) { return pa2u[i].u; } } ca2u++; pa2u = (pA2U) mir_realloc(pa2u,sizeof(A2U)*ca2u); pa2u[i].a = (LPSTR) lpText; if( bCoreUnicode ) { LPWSTR lpwText = mir_a2u(lpText); LPWSTR lpwTran = TranslateW(lpwText); mir_free(lpwText); pa2u[i].u = mir_strdup(exp->utf8encode(lpwTran)); } else { LPSTR lpTran = Translate(lpText); LPWSTR lpwTran = mir_a2u(lpTran); lpTran = exp->utf8encode(lpwTran); mir_free(lpwTran); pa2u[i].u = mir_strdup(lpTran); } return pa2u[i].u; }
int msgbox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { LPWSTR lpwText = mir_a2u(lpText); LPWSTR lpwCaption = mir_a2u(lpCaption); int r = MessageBoxW(hWnd, TranslateW(lpwText), TranslateW(lpwCaption), uType); mir_free(lpwCaption); mir_free(lpwText); return r; }
void bayes_approve_contact(MCONTACT hContact) { const char *message; TCHAR *messageW; int d = 0; sqlite3_stmt *stmt; if (bayesdb == NULL) return; sqlite3_prepare_v2(bayesdb, "SELECT message FROM queue WHERE contact=?", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, (DWORD)hContact); while (sqlite3_step(stmt) == SQLITE_ROW) { d = 1; message = (char*)sqlite3_column_text(stmt, 0); messageW = mir_a2u(message); learn_ham(messageW); mir_free(messageW); } sqlite3_finalize(stmt); if (d) { sqlite3_prepare_v2(bayesdb, "DELETE FROM queue WHERE contact=?", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, (DWORD)hContact); sqlite3_step(stmt); sqlite3_finalize(stmt); } }
TCHAR* ReqGetText(DBEVENTINFO* dbei) { if ( !dbei->pBlob ) return 0; char * ptr=(char *)&dbei->pBlob[sizeof(DWORD)*2]; int len=dbei->cbBlob-sizeof(DWORD)*2; int i=0; while(len && (i<4)) { if(!ptr[0]) i++; ptr++; len--; }; if(len) { char * tstr=(char *)mir_alloc(len+1); memcpy(tstr, ptr, len); tstr[len]=0; WCHAR* msg = NULL; msg=(dbei->flags&DBEF_UTF)?mir_utf8decodeW(tstr):mir_a2u(tstr); mir_free(tstr); return (TCHAR *)msg; }; return 0; }
/** * return the country name * * @param ci - pointer to a CONTACTINFO structure holding information about the contact * @param pszSetting - the desired setting to read the countrys id from * * @retval 0 - if setting was found and read correctly * @retval 1 - if any error occured or setting was not found **/ static FORCEINLINE INT_PTR GCICountry(CONTACTINFO *ci, LPCSTR pszSetting) { if (0 == GCIVarEx(ci, pszSetting)) { if (ci->type != CNFT_ASCIIZ) { // country id was safed in database as code UINT res = 0; switch (ci->type) { case CNFT_WORD: res = ci->wVal; break; case CNFT_DWORD: res = ci->dVal; break; default: return 1; } // LPSTR szCountry = res ? (LPSTR)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, res, 0) : NULL; LPSTR szCountry = res ? (LPSTR)ServiceGetCountryByNumber(res, 0) : NULL; if (szCountry) { ci->pszVal = (ci->dwFlag & CNF_UNICODE) ? (LPTSTR) mir_a2u(szCountry) : (LPTSTR) mir_strdup(szCountry); } else { ci->pszVal = NULL; } ci->type = (ci->pszVal != NULL) ? CNFT_ASCIIZ : 0; } } else { ci->type = 0; } return ci->type == 0; }
/** * This function tries to read a Language from a certain module (e.g. USERINFO) and if failed it * tries once again with the baseprotocol of the contact (e.g. ICQ). If nothing was found anyway * and this is an metacontact it can have a look into subcontacts to retrieve the information. * This depends on the settings the user did. * * @warning ci MUST NOT be NULL! * * @param ci - pointer to a CONTACTINFO structure holding information about the contact * @param pszSetting - the desired setting to read * * @retval 0 - if setting was found and read correctly * @retval 1 - if any error occured or setting was not found **/ static FORCEINLINE INT_PTR GCILangEx(CONTACTINFO *ci, LPCSTR pszSetting) { if (0 == GCIVarEx(ci, pszSetting)) { if(ci->type!= CNFT_ASCIIZ) { //lang was safed in database as code LPIDSTRLIST pList; UINT nList, i, res = 0; switch (ci->type) { case CNFT_BYTE: res = ci->bVal; break; case CNFT_WORD: res = ci->wVal; break; case CNFT_DWORD: res = ci->dVal; break; default: return 1; } GetLanguageList(&nList, &pList); for(i = 0; i<nList; i++) { if(pList[i].nID == res) { //use untranslate string (pszText member) ci->pszVal = (ci->dwFlag & CNF_UNICODE) ? (LPTSTR) mir_a2u(pList[i].pszText) : (LPTSTR) mir_strdup(pList[i].pszText); ci->type = (ci->pszVal != NULL) ? CNFT_ASCIIZ : 0; return 0; } } /*end for*/ ci->type = 0; ci->pszVal = NULL; } } else { ci->type = 0; } return ci->type == 0; }
void dequeue_messages() { time_t t = time(NULL); sqlite3_stmt *stmt; const char *message; TCHAR *messageW; int d = 0; if (bayesdb == NULL) return; sqlite3_prepare_v2(bayesdb, "SELECT message FROM queue WHERE msgtime + ? < ?", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, _getOptD("BayesWaitApprove", defaultBayesWaitApprove)*86400); sqlite3_bind_int(stmt, 2, (DWORD)t); while (sqlite3_step(stmt) == SQLITE_ROW) { d = 1; message = (char*)sqlite3_column_text(stmt, 0); messageW = mir_a2u(message); learn_spam(messageW); mir_free(messageW); } sqlite3_finalize(stmt); if (d) { sqlite3_prepare_v2(bayesdb, "DELETE FROM queue WHERE msgtime + ? < ?", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, _getOptD("BayesWaitApprove", defaultBayesWaitApprove)*86400); sqlite3_bind_int(stmt, 2, (DWORD)t); sqlite3_step(stmt); sqlite3_finalize(stmt); } }
void wSetData(WCHAR **Data, const char *Value) { if (Value[0] != 0) *Data = mir_a2u(Value); else *Data = L""; }
static size_t utf8toutf16(char* str, wchar_t* res) { wchar_t *dec = mir_utf8decodeW(str); if (dec == NULL) dec = mir_a2u(str); wcscpy(res, dec); mir_free(dec); return wcslen(res); }
void logRegister(){ // Register netlib user for logging function NETLIBUSER nlu = { 0 }; nlu.cbSize = sizeof(nlu); nlu.flags = NUF_TCHAR | NUF_NOOPTIONS; nlu.szSettingsModule = PLUGINNAME; nlu.ptszDescriptiveName = mir_a2u(PLUGINNAME); netlibHandle = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); }
void getContactUin(HANDLE hContact, LPSTR szUIN) { getContactUinA(hContact, szUIN); if (*szUIN) { LPWSTR tmp = mir_a2u(szUIN); wcscpy((LPWSTR)szUIN, tmp); mir_free(tmp); } }
static INT_PTR CB_AddButton(WPARAM, LPARAM lParam) { BBButton *bbdi = (BBButton *)lParam; if (!bbdi || bbdi->cbSize != sizeof(BBButton)) return 1; CustomButtonData *cbd = new CustomButtonData(); if (!bbdi->iButtonWidth && (bbdi->bbbFlags & BBBF_ISARROWBUTTON)) cbd->iButtonWidth = DPISCALEX_S(34); else if (!bbdi->iButtonWidth) cbd->iButtonWidth = DPISCALEX_S(22); else cbd->iButtonWidth = DPISCALEX_S(bbdi->iButtonWidth); cbd->pszModuleName = mir_strdup(bbdi->pszModuleName); if (bbdi->ptszTooltip) { if (bbdi->bbbFlags & BBBF_ANSITOOLTIP) cbd->ptszTooltip = mir_a2u(bbdi->pszTooltip); else cbd->ptszTooltip = mir_tstrdup(bbdi->ptszTooltip); } else cbd->ptszTooltip = NULL; cbd->dwButtonOrigID = bbdi->dwButtonID; cbd->hIcon = bbdi->hIcon; cbd->dwPosition = bbdi->dwDefPos; cbd->dwButtonCID = (bbdi->bbbFlags & BBBF_CREATEBYID) ? bbdi->dwButtonID : LastCID; //ugly workaround for smileys plugins cbd->dwArrowCID = (bbdi->bbbFlags & BBBF_ISARROWBUTTON) ? (cbd->dwButtonCID == IDOK ? IDC_SENDMENU : (cbd->dwButtonCID + 1)) : 0; cbd->bHidden = (bbdi->bbbFlags & BBBF_HIDDEN) != 0; cbd->bLSided = (bbdi->bbbFlags & BBBF_ISLSIDEBUTTON) != 0; cbd->bRSided = (bbdi->bbbFlags & BBBF_ISRSIDEBUTTON) != 0; cbd->bCanBeHidden = (bbdi->bbbFlags & BBBF_CANBEHIDDEN) != 0; cbd->bSeparator = (bbdi->bbbFlags & BBBF_ISDUMMYBUTTON) != 0; cbd->bChatButton = (bbdi->bbbFlags & BBBF_ISCHATBUTTON) != 0; cbd->bIMButton = (bbdi->bbbFlags & BBBF_ISIMBUTTON) != 0; cbd->bDisabled = (bbdi->bbbFlags & BBBF_DISABLED) != 0; cbd->bPushButton = (bbdi->bbbFlags & BBBF_ISPUSHBUTTON) != 0; CB_GetButtonSettings(NULL, cbd); if (cbd->bLSided) LButtonsList.insert(cbd); else if (cbd->bRSided) RButtonsList.insert(cbd); else return 1; if (cbd->dwButtonCID != cbd->dwButtonOrigID) LastCID++; if (cbd->dwArrowCID == LastCID) LastCID++; M.BroadcastMessage(DM_BBNEEDUPDATE, 0, 0); return 0; }
void showPopupMsg(HANDLE hContact, LPCSTR lpzText, HICON hIcon, int type) { // type: // 0 - error // 1 - key sent // 2 - key recv // 3 - established // 4 - disabled // 5 - msg recv // 6 - msg sent // if(!bPopupExists) return; char nback[32]; mir_snprintf(nback,sizeof(nback),"popup%dback", $type); char ntext[32]; mir_snprintf(ntext,sizeof(ntext),"popup%dtext", $type); char ntime[32]; mir_snprintf(ntime,sizeof(ntime),"popup%dtime", $type); COLORREF colorBack = (COLORREF)DBGetContactSettingDword(0,szModuleName,nback,(DWORD)RGB(230,230,255)); COLORREF colorText = (COLORREF)DBGetContactSettingDword(0,szModuleName,ntext,(DWORD)RGB(0,0,0)); int timeout = (int)DBGetContactSettingWord(0,szModuleName,ntime,0); if( bCoreUnicode && bPopupUnicode ) { POPUPDATAW ppd; memset(&ppd,0,sizeof(POPUPDATAW)); ppd.lchContact = hContact; ppd.lchIcon = hIcon; LPWSTR lpwzContactName = (LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCMDF_UNICODE); wcscpy(ppd.lpwzContactName, lpwzContactName); LPWSTR lpwzText = mir_a2u(lpzText); wcscpy(ppd.lpwzText, TranslateW(lpwzText)); mir_free(lpwzText); ppd.colorBack = colorBack; ppd.colorText = colorText; ppd.iSeconds = timeout; // ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; // ppd.PluginData = NULL; CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&ppd, 0); } else { POPUPDATAEX ppd; memset(&ppd,0,sizeof(POPUPDATAEX)); ppd.lchContact = hContact; ppd.lchIcon = hIcon; LPSTR lpzContactName = (LPSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); strcpy(ppd.lpzContactName, lpzContactName); strcpy(ppd.lpzText, Translate(lpzText)); ppd.colorBack = colorBack; ppd.colorText = colorText; ppd.iSeconds = timeout; // ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; // ppd.PluginData = NULL; CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); } }
static INT_PTR CB_ModifyButton(WPARAM, LPARAM lParam) { BBButton *bbdi = (BBButton *)lParam; if (!bbdi) return 1; bool bFound = 1; CustomButtonData *cbd = NULL; { mir_cslock lck(ToolBarCS); for (int i = 0; i < LButtonsList.getCount(); i++) { cbd = LButtonsList[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { bFound = true; break; } } if (!bFound) { for (int i = 0; i < RButtonsList.getCount(); i++) { cbd = RButtonsList[i]; if (!strcmp(cbd->pszModuleName, bbdi->pszModuleName) && (cbd->dwButtonOrigID == bbdi->dwButtonID)) { bFound = true; break; } } } if (bFound) { if (bbdi->pszTooltip) { mir_free(cbd->ptszTooltip); if (bbdi->bbbFlags & BBBF_ANSITOOLTIP) cbd->ptszTooltip = mir_a2u(bbdi->pszTooltip); else cbd->ptszTooltip = mir_tstrdup(bbdi->ptszTooltip); } if (bbdi->hIcon) cbd->hIcon = bbdi->hIcon; if (bbdi->bbbFlags) { cbd->bHidden = (bbdi->bbbFlags & BBBF_HIDDEN) != 0; cbd->bLSided = (bbdi->bbbFlags & BBBF_ISLSIDEBUTTON) != 0; cbd->bRSided = (bbdi->bbbFlags & BBBF_ISRSIDEBUTTON) != 0; cbd->bCanBeHidden = (bbdi->bbbFlags & BBBF_CANBEHIDDEN) != 0; cbd->bChatButton = (bbdi->bbbFlags & BBBF_ISCHATBUTTON) != 0; cbd->bIMButton = (bbdi->bbbFlags & BBBF_ISIMBUTTON) != 0; cbd->bDisabled = (bbdi->bbbFlags & BBBF_DISABLED) != 0; } } } if (bFound) M.BroadcastMessage(DM_BBNEEDUPDATE, 0, (LPARAM)cbd); return 0; }
static int RenameGroup(WPARAM wParam,LPARAM lParam) { #if defined( _UNICODE ) WCHAR* temp = mir_a2u(( char* )lParam ); int result = ( -1 != RenameGroupWithMove(wParam - 1, temp, 1)); mir_free( temp ); return result; #else return -1 != RenameGroupWithMove(wParam - 1, (TCHAR*) lParam, 1); #endif }
void showPopup(LPCSTR lpzText,HANDLE hContact,HICON hIcon, UINT type) { //type=0 key colors //type=1 session colors //type=2 SR colors if (!bPopupExists) return; COLORREF colorBack, colorText; int timeout=0; DBVARIANT dbv; if (type == 0) { colorBack = db_get_dw(0, MODULENAME, "colorKeyb", RGB(230,230,255)); colorText = db_get_dw(0, MODULENAME, "colorKeyt", RGB(0,0,0)); if (!db_get_s(0, MODULENAME, "timeoutKey", &dbv)) { timeout = atoi(dbv.pszVal); db_free(&dbv); } } else if (type == 1) { colorBack = db_get_dw(0, MODULENAME, "colorSecb", RGB(255,255,200)); colorText = db_get_dw(0, MODULENAME, "colorSect", RGB(0,0,0)); if (!db_get_s(0, MODULENAME, "timeoutSec" ,&dbv)) { timeout = atoi(dbv.pszVal); db_free(&dbv); } } else if (type >= 2) { colorBack = db_get_dw(0, MODULENAME, "colorSRb", RGB(200,255,200)); colorText = db_get_dw(0, MODULENAME, "colorSRt", RGB(0,0,0)); if (!db_get_s(0, MODULENAME, "timeoutSR", &dbv)) { timeout = atoi(dbv.pszVal); db_free(&dbv); } } POPUPDATAW ppd = {0}; ppd.lchContact = hContact; //Be sure to use a GOOD handle, since this will not be checked. ppd.lchIcon = hIcon; LPWSTR lpwzContactName = (LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GSMDF_UNICODE); wcscpy(ppd.lpwzContactName, lpwzContactName); LPWSTR lpwzText = mir_a2u(lpzText); wcscpy(ppd.lpwzText, TranslateW(lpwzText)); mir_free(lpwzText); ppd.colorBack = colorBack; ppd.colorText = colorText; ppd.iSeconds = timeout; PUAddPopupW(&ppd); }
MIR_APP_DLL(HGENMENU) Menu_AddItem(int hMenuObject, TMO_MenuItem *pmi, void *pUserData) { if (!bIsGenMenuInited || pmi == NULL) return NULL; mir_cslock lck(csMenuHook); TIntMenuObject *pmo = GetMenuObjbyId(hMenuObject); if (pmo == NULL) return NULL; TMO_IntMenuItem* p = (TMO_IntMenuItem*)mir_calloc(sizeof(TMO_IntMenuItem)); p->parent = pmo; p->signature = MENUITEM_SIGNATURE; p->iCommand = GetNextObjectMenuItemId(); p->mi = *pmi; p->iconId = -1; p->originalPosition = pmi->position; p->pUserData = pUserData; if (pmi->flags & CMIF_UNICODE) p->mi.name.t = mir_tstrdup(pmi->name.t); else p->mi.name.t = mir_a2u(pmi->name.a); if (pmi->hIcon != NULL && !bIconsDisabled) { HANDLE hIcolibItem = IcoLib_IsManaged(pmi->hIcon); if (hIcolibItem != NULL) { HICON hIcon = IcoLib_GetIconByHandle(hIcolibItem, false); p->iconId = ImageList_AddIcon(pmo->m_hMenuIcons, hIcon); p->hIcolibItem = hIcolibItem; IcoLib_ReleaseIcon(hIcon); } else p->iconId = ImageList_AddIcon(pmo->m_hMenuIcons, pmi->hIcon); } TMO_IntMenuItem *pRoot = (p->mi.root != NULL) ? MO_GetIntMenuItem(p->mi.root) : NULL; if (pRoot) { p->owner = &pRoot->submenu; if (pRoot->iconId == -1) pRoot->iconId = p->iconId; } else p->owner = &pmo->m_items; if (!p->owner->first) p->owner->first = p; if (p->owner->last) p->owner->last->next = p; p->owner->last = p; return p; }
// преобразуем текст из формата миранды в чистый UTF8 LPSTR miranda_to_utf8(LPCSTR szMirMsg, DWORD flags) { LPSTR szNewMsg; if (flags & PREF_UTF) szNewMsg = (LPSTR)szMirMsg; else if (flags & PREF_UNICODE) szNewMsg = exp->utf8encode((LPCWSTR)(szMirMsg + strlen(szMirMsg) + 1)); else { LPWSTR wszMirMsg = mir_a2u(szMirMsg); szNewMsg = exp->utf8encode(wszMirMsg); mir_free(wszMirMsg); } return mir_strdup(szNewMsg); }
inline std::wstring GetProtocolName(MCONTACT hContact) { char* ac = (char *)CallService(MS_PROTO_GETCONTACTBASEACCOUNT, hContact, 0); std::wstring proto1; if (ac != NULL) { PROTOACCOUNT* acnt = ProtoGetAccount(ac); if (acnt != NULL && acnt->szModuleName != NULL) { wchar_t* proto = mir_a2u(acnt->szProtoName); proto1 = proto; mir_free(proto); } } return proto1; }
static HWND ModernSkinButtonCreateWindow(ModernSkinButtonCtrl * bct, HWND parent) { HWND hwnd; if (bct == nullptr) return FALSE; { wchar_t *UnicodeID = mir_a2u(bct->ID); hwnd = CreateWindow(_A2W(MODERNSKINBUTTONCLASS), UnicodeID, WS_VISIBLE | WS_CHILD, bct->Left, bct->Top, bct->Right - bct->Left, bct->Bottom - bct->Top, parent, nullptr, g_plugin.getInst(), nullptr); mir_free(UnicodeID); } bct->hwnd = hwnd; bct->focus = 0; SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)bct); return hwnd; }
INT_PTR SendMessageCommand_Worker(MCONTACT hContact, LPCSTR pszMsg, bool isWchar) { // make sure that only the main UI thread will handle window creation if (GetCurrentThreadId() != PluginConfig.dwThreadID) { if (pszMsg) { wchar_t *tszText = (isWchar) ? mir_wstrdup((WCHAR*)pszMsg) : mir_a2u(pszMsg); PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_SENDMESSAGECOMMANDW, hContact, (LPARAM)tszText); } else PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_SENDMESSAGECOMMANDW, hContact, 0); return 0; } // does the MCONTACT's protocol support IM messages? char *szProto = GetContactProto(hContact); if (szProto == NULL) return 0; // unknown contact if (!CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND) return 0; HWND hwnd = M.FindWindow(hContact); if (hwnd) { if (pszMsg) { HWND hEdit = GetDlgItem(hwnd, IDC_MESSAGE); SendMessage(hEdit, EM_SETSEL, -1, GetWindowTextLength(hEdit)); if (isWchar) SendMessageW(hEdit, EM_REPLACESEL, FALSE, (LPARAM)pszMsg); else SendMessageA(hEdit, EM_REPLACESEL, FALSE, (LPARAM)pszMsg); } SendMessage(hwnd, DM_ACTIVATEME, 0, 0); } else { TCHAR szName[CONTAINER_NAMELEN + 1]; GetContainerNameForContact(hContact, szName, CONTAINER_NAMELEN); TContainerData *pContainer = FindContainerByName(szName); if (pContainer == NULL) pContainer = CreateContainer(szName, FALSE, hContact); if (pContainer) CreateNewTabForContact(pContainer, hContact, isWchar, pszMsg, TRUE, TRUE, FALSE, 0); } return 0; }
int GetValueW(MCONTACT hContact, const char *module, const char *setting, WCHAR *value, int length) { DBVARIANT dbv = { 0 }; if (!module || !setting || !value) return 0; if (length >= 10 && !db_get_s(hContact, module, setting, &dbv, 0)) { switch (dbv.type) { case DBVT_ASCIIZ: mir_wstrncpy(value, ptrW(mir_a2u(dbv.pszVal)), length); break; case DBVT_DWORD: case DBVT_WORD: case DBVT_BYTE: _ultow(getNumericValue(&dbv), value, 10); break; case DBVT_WCHAR: mir_wstrncpy(value, dbv.pwszVal, length); break; case DBVT_UTF8: mir_wstrncpy(value, ptrW(mir_utf8decodeW(dbv.pszVal)), length); break; case DBVT_DELETED: value[0] = 0; return 0; } int type = dbv.type; db_free(&dbv); return type; } value[0] = 0; return 0; }
void IEEmbed::navigate(NETLIBHTTPREQUEST *nlhr) { WCHAR *szUrl = mir_a2u(nlhr->szUrl); BSTR bstrHeaders; LPSAFEARRAY psa; LPSTR pPostData; VARIANT vPostData = {0}, vHeaders = {0}; bstrHeaders = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n"); V_VT(&vHeaders) = VT_BSTR; V_BSTR(&vHeaders) = bstrHeaders; VariantInit(&vPostData); psa = SafeArrayCreateVector(VT_UI1, 0, nlhr->dataLength); SafeArrayAccessData(psa, (LPVOID*)&pPostData); memcpy(pPostData, nlhr->pData, nlhr->dataLength); SafeArrayUnaccessData(psa); V_VT(&vPostData) = VT_ARRAY | VT_UI1; V_ARRAY(&vPostData) = psa; pWebBrowser->Navigate(szUrl, NULL, NULL, &vPostData, &vHeaders); SysFreeString(bstrHeaders); VariantClear(&vPostData); mir_free(szUrl); }
INT_PTR CALLBACK DlgProcPopupActions(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static bool windowInitialized = false; static UINT controls[] = { IDC_GRP_CUSTOMACTIONS, IDC_TXT_CUSTOMACTIONS, IDC_CHK_IMCONTACTSONLY, IDC_CHK_CONTACTSONLY, IDC_CHK_DONTCLOSE, IDC_GRP_SIZEPOSITION, IDC_CHK_LARGEICONS, IDC_TXT_POSITION, IDC_RD_TEXT, IDC_RD_LEFTICONS, IDC_RD_RIGHTICONS, IDC_GRP_ACTIONS, IDC_ACTIONS, IDC_GRP_SIZEPOSITION2, IDC_TXT_POSITION2, IDC_CB_LEFT, IDC_TXT_MIDDLE, IDC_CB_MIDDLE, IDC_TXT_RIGHT, IDC_CB_RIGHT }; switch (msg) { case WM_INITDIALOG: { int i; windowInitialized = false; TranslateDialogDefault(hwnd); SendMessage(GetDlgItem(hwnd, IDC_ICO_INFO), STM_SETICON, (WPARAM)IcoLib_GetIcon(ICO_MISC_NOTIFY,0), 0); CheckDlgButton(hwnd, IDC_CHK_ENABLEACTIONS, PopUpOptions.actions&ACT_ENABLE ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_CHK_IMCONTACTSONLY, PopUpOptions.actions&ACT_DEF_IMONLY ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_CHK_CONTACTSONLY, PopUpOptions.actions&ACT_DEF_NOGLOBAL ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_CHK_DONTCLOSE, PopUpOptions.actions&ACT_DEF_KEEPWND ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_CHK_LARGEICONS, PopUpOptions.actions&ACT_LARGE ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_RD_TEXT, PopUpOptions.actions&ACT_TEXT ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_RD_LEFTICONS, PopUpOptions.actions&ACT_LEFTICONS ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_RD_RIGHTICONS, PopUpOptions.actions&ACT_RIGHTICONS ? TRUE : FALSE); { DWORD dwActiveItem = 0; HWND hCombo = GetDlgItem(hwnd, IDC_CB_LEFT); dwActiveItem = MouseOverride(hCombo, PopUpOptions.overrideLeft); SendDlgItemMessage(hwnd, IDC_CB_LEFT, CB_SETCURSEL, dwActiveItem, 0); dwActiveItem = 0; hCombo = GetDlgItem(hwnd, IDC_CB_MIDDLE); dwActiveItem = MouseOverride(hCombo, PopUpOptions.overrideMiddle); SendDlgItemMessage(hwnd, IDC_CB_MIDDLE, CB_SETCURSEL, dwActiveItem, 0); dwActiveItem = 0; hCombo = GetDlgItem(hwnd, IDC_CB_RIGHT); dwActiveItem = MouseOverride(hCombo, PopUpOptions.overrideRight); SendDlgItemMessage(hwnd, IDC_CB_RIGHT, CB_SETCURSEL, dwActiveItem, 0); } HWND hwndList = GetDlgItem(hwnd, IDC_ACTIONS); ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_CHECKBOXES|LVS_EX_LABELTIP); HIMAGELIST hImgList = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 10, 1); ListView_SetImageList(hwndList, hImgList, LVSIL_SMALL); LVCOLUMN column = {0}; column.mask = LVCF_TEXT|LVCF_WIDTH; column.pszText = TranslateT("Action"); column.cx = 175; ListView_InsertColumn(hwndList, 0, &column); if (IsWinVerXPPlus()) ListView_EnableGroupView(hwndList, TRUE); LIST<char> groups(1, strcmp); for (i = 0; i < gActions.getCount(); ++i) { char szGroup[64]; char *szName = strchr(gActions[i]->lpzTitle, '/'); if (!szName) szName = gActions[i]->lpzTitle; else ++szName; lstrcpynA(szGroup, gActions[i]->lpzTitle, szName - gActions[i]->lpzTitle); int grpId = 0; if (IsWinVerXPPlus() && ((grpId = groups.getIndex(szGroup)) < 0)) { LVGROUP group = {0}; group.cbSize = sizeof(group); group.mask = LVGF_HEADER|LVGF_GROUPID; LPWSTR wszGroup = mir_a2u(szGroup); group.pszHeader = TranslateW(wszGroup); group.cchHeader = lstrlenW(wszGroup); grpId = group.iGroupId = groups.getCount(); int grpId = ListView_InsertGroup(hwndList, -1, &group); mir_free(wszGroup); groups.insert(mir_strdup(szGroup), groups.getCount()); } if (g_popup.isOsUnicode) { LVITEMW item = {0}; item.mask = LVIF_IMAGE|LVIF_PARAM|LVIF_TEXT|LVIF_STATE|LVIF_INDENT; item.iItem = i; LPWSTR wszName = mir_a2u(szName); item.pszText = TranslateW(wszName); item.iImage = ImageList_AddIcon(hImgList, gActions[i]->lchIcon); item.lParam = i; if (IsWinVerXPPlus()) { item.mask |= LVIF_GROUPID; item.iGroupId = grpId; } item.iIndent = 0; ListView_InsertItemW(hwndList, &item); mir_free(wszName); } else { LVITEMA item = {0}; item.mask = LVIF_IMAGE|LVIF_PARAM|LVIF_TEXT|LVIF_STATE|LVIF_GROUPID|LVIF_INDENT; item.iItem = i; item.pszText = Translate(szName); item.iImage = ImageList_AddIcon(hImgList, gActions[i]->lchIcon); item.lParam = i; item.iGroupId = grpId; item.iIndent = 0; ListView_InsertItem(hwndList, &item); } ListView_SetItemState(hwndList, i, (gActions[i]->flags & PAF_ENABLED) ? 0x2000 : 0x1000, LVIS_STATEIMAGEMASK); } groups.destroy(); BOOL enabled = (PopUpOptions.actions&ACT_ENABLE) ? TRUE : FALSE; for (i = 0; i < SIZEOF(controls); ++i) EnableWindow(GetDlgItem(hwnd, controls[i]), enabled); windowInitialized = true; break; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_CHK_ENABLEACTIONS: { PopUpOptions.actions &= ~ACT_ENABLE; PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_ENABLEACTIONS) ? ACT_ENABLE : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); BOOL enabled = (PopUpOptions.actions&ACT_ENABLE) ? TRUE : FALSE; for (int i = 0; i < SIZEOF(controls); ++i) EnableWindow(GetDlgItem(hwnd, controls[i]), enabled); break; } case IDC_CHK_IMCONTACTSONLY: PopUpOptions.actions &= ~ACT_DEF_IMONLY; PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_IMCONTACTSONLY) ? ACT_DEF_IMONLY : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_CHK_CONTACTSONLY: PopUpOptions.actions &= ~ACT_DEF_NOGLOBAL; PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_CONTACTSONLY) ? ACT_DEF_NOGLOBAL : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_CHK_DONTCLOSE: PopUpOptions.actions &= ~ACT_DEF_KEEPWND; PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_DONTCLOSE) ? ACT_DEF_KEEPWND : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_CHK_LARGEICONS: PopUpOptions.actions &= ~ACT_LARGE; PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_LARGEICONS) ? ACT_LARGE : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_RD_TEXT: PopUpOptions.actions &= ~(ACT_TEXT|ACT_LEFTICONS|ACT_RIGHTICONS); PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_CHK_ENABLEACTIONS) ? ACT_TEXT : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_RD_LEFTICONS: PopUpOptions.actions &= ~(ACT_TEXT|ACT_LEFTICONS|ACT_RIGHTICONS); PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_RD_LEFTICONS) ? ACT_LEFTICONS : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_RD_RIGHTICONS: PopUpOptions.actions &= ~(ACT_TEXT|ACT_LEFTICONS|ACT_RIGHTICONS); PopUpOptions.actions |= IsDlgButtonChecked(hwnd, IDC_RD_RIGHTICONS) ? ACT_RIGHTICONS : 0; SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; case IDC_PREVIEW: PopUpPreview(); break; case IDC_CB_LEFT: case IDC_CB_MIDDLE: case IDC_CB_RIGHT: PopUpOptions.overrideLeft = SendDlgItemMessage(hwnd, IDC_CB_LEFT, CB_GETITEMDATA, SendDlgItemMessage(hwnd, IDC_CB_LEFT, CB_GETCURSEL,0,0),0); PopUpOptions.overrideMiddle = SendDlgItemMessage(hwnd, IDC_CB_MIDDLE, CB_GETITEMDATA, SendDlgItemMessage(hwnd, IDC_CB_MIDDLE, CB_GETCURSEL,0,0),0); PopUpOptions.overrideRight = SendDlgItemMessage(hwnd, IDC_CB_RIGHT, CB_GETITEMDATA, SendDlgItemMessage(hwnd, IDC_CB_RIGHT, CB_GETCURSEL,0,0),0); SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); break; } break; } case WM_NOTIFY: { switch (((LPNMHDR)lParam)->idFrom) { case 0: { switch (((LPNMHDR)lParam)->code) { case PSN_RESET: LoadOption_Actions(); break; case PSN_APPLY: { DBWriteContactSettingDword(NULL, MODULNAME, "Actions", PopUpOptions.actions); HWND hwndList = GetDlgItem(hwnd, IDC_ACTIONS); for (int i = 0; i < gActions.getCount(); ++i) { gActions[i]->flags = (ListView_GetItemState(hwndList, i, LVIS_STATEIMAGEMASK) == 0x2000) ? PAF_ENABLED : 0; DBWriteContactSettingByte(NULL, "PopUpActions", gActions[i]->lpzTitle, (gActions[i]->flags&PAF_ENABLED) ? 1 : 0); } //overrideActions DBWriteContactSettingDword(NULL, MODULNAME, "OverrideLeft", PopUpOptions.overrideLeft); DBWriteContactSettingDword(NULL, MODULNAME, "OverrideMiddle", PopUpOptions.overrideMiddle); DBWriteContactSettingDword(NULL, MODULNAME, "OverrideRight", PopUpOptions.overrideRight); break; } } break; } case IDC_ACTIONS: { NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; if (windowInitialized && nmlv && nmlv->hdr.code == LVN_ITEMCHANGED && nmlv->uOldState != 0 && (nmlv->uNewState == 0x1000 || nmlv->uNewState == 0x2000)) { SendMessage(GetParent(hwnd), PSM_CHANGED,0,0); } break; } } break; } } return FALSE; }
int OnDBEventFilterAdd(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; DBEVENTINFO *dbei = (DBEVENTINFO *)lParam; char *msgblob; POPUPDATA ppdp = {0}; DBTIMETOSTRING tts = {0}; char protoOption[256] = {0}; char *response, *tmp, *challenge; int buflen = MAX_BUFFER_LENGTH; TCHAR buf[MAX_BUFFER_LENGTH]; TCHAR *message = NULL, *challengeW = NULL, *tmpW = NULL; TCHAR *whitelist = NULL, *ptok; TCHAR mexpr[64]; int maxmsglen = 0, a, b, i; BOOL bayesEnabled = _getOptB("BayesEnabled", defaultBayesEnabled); BOOL bCorrectResponse = FALSE; // get hContact from DBEVENTINFO as icq_proto.c doesn't pass hContact the usual way for some reason. if (dbei->eventType == EVENTTYPE_AUTHREQUEST) hContact = *((PHANDLE)(dbei->pBlob+sizeof(DWORD))); // get maximum length of the message a protocol supports maxmsglen = CallProtoService(dbei->szModule, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, (LPARAM)hContact); /*** Dequeue and learn messages ***/ if (bayesEnabled && _getOptB("BayesAutolearnNotApproved", defaultBayesAutolearnNotApproved)) if (time(NULL) - last_queue_check > 4*3600) { // dequeue every 4 hours dequeue_messages(); last_queue_check = time(NULL); } /*** Check for conditional and unconditional approval ***/ // Pass-through if protocol is not enabled strcat(protoOption, "proto_"); strcat(protoOption, dbei->szModule); if (_getOptB(protoOption, 0) == 0) // Protocol is not handled by Spam-o-tron return 0; // Pass-through if the event is not of type EVENTTYPE_MESSAGE or EVENTTYPE_AUTHREQUEST if (dbei->eventType != EVENTTYPE_MESSAGE && dbei->eventType != EVENTTYPE_AUTHREQUEST) return 0; // Pass-through if contact is already verified. if (_getCOptB(hContact, "Verified", 0) == 1) return 0; // Pass-through if the event is already read. if (dbei->flags & DBEF_READ) return 0; // Pass-through if event is from a contact that is already in the list. if (db_get_b(hContact, "CList", "NotOnList", 1) == 0) // Already in the list return 0; // Pass-through if event is from a contact that is already in the server-side contact list if (db_get_w(hContact, dbei->szModule, "ServerId", 0)) return 0; // Pass-through if contact is a MetaContact if (db_get_dw(hContact, "MetaContacts", "NumContacts", 0)) return 0; // Pass-through and approve if outgoing event. if (dbei->flags & DBEF_SENT) { if (_getOptB("ApproveOnMsgOut", 0)) { _setCOptB(hContact, "Verified", 1); if (_getOptB("AddPermanently", defaultAddPermanently)) db_unset(hContact, "CList", "NotOnList"); db_unset(hContact, "CList", "Delete"); } return 0; } // Hide the contact until verified if option set. if (_getOptB("HideUnverified", defaultHideUnverified)) db_set_b(hContact, "CList", "Hidden", 1); // Fetch the incoming message body if (dbei->eventType == EVENTTYPE_MESSAGE) { msgblob = (char *)dbei->pBlob; } else if (dbei->eventType == EVENTTYPE_AUTHREQUEST) { msgblob = (char *)(dbei->pBlob + sizeof(DWORD) + sizeof(HANDLE)); for(a=4;a>0;a--) msgblob += strlen(msgblob)+1; } if (dbei->flags & DBEF_UTF) message = mir_utf8decodeW(msgblob); else message = mir_a2u(msgblob); /*** Check for words in white-list ***/ if (_getOptB("ApproveOnMsgIn", defaultApproveOnMsgIn)) { whitelist = (TCHAR*)malloc(2048 * sizeof(TCHAR)); if (whitelist != NULL) { _getOptS(whitelist, 2048, "ApproveOnMsgInWordlist", defaultApproveOnMsgInWordlist); if (_isregex(whitelist)) { if (_regmatch(message, whitelist)) bCorrectResponse = TRUE; } else { ptok = _tcstok(whitelist, L" "); while (ptok != NULL) { if (_tcsstr(message, ptok)) { bCorrectResponse = TRUE; break; } ptok = _tcstok(NULL, L" "); } } free(whitelist); if (bCorrectResponse) { _setCOptB(hContact, "Verified", 1); if (_getOptB("HideUnverified", defaultHideUnverified)) db_unset(hContact, "CList", "Hidden"); if (_getOptB("AddPermanently", defaultAddPermanently)) db_unset(hContact, "CList", "NotOnList"); db_unset(hContact, "CList", "Delete"); if (_getOptB("ReplyOnSuccess", defaultReplyOnSuccess) && (_getCOptB(hContact, "MsgSent", 0))) { tmp = mir_u2a(_getOptS(buf, buflen, "SuccessResponse", defaultSuccessResponse)); response = mir_utf8encode(tmp); mir_free(tmp); CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)response); mir_free(response); } return 0; } } } /*** Check for correct answer ***/ switch (_getOptB("Mode", defaultMode)) { case SPAMOTRON_MODE_ROTATE: case SPAMOTRON_MODE_RANDOM: get_response(buf, buflen, _getCOptD(hContact, "ResponseNum", 0)); if (_isregex(buf)) { if (_regmatch(message, buf)) bCorrectResponse = TRUE; } else { if (_tcsstr_cc(message, buf, _getOptB("ResponseCC", defaultResponseCC)) && (_tcslen(message) == _tcslen(buf))) bCorrectResponse = TRUE; } break; case SPAMOTRON_MODE_PLAIN: _getOptS(buf, buflen, "Response", defaultResponse); i = get_response_num(buf); while (i-- > 0) { get_response(buf, buflen, i-1); if (_isregex(buf)) { if (_regmatch(message, buf)) { bCorrectResponse = TRUE; break; } } else { if (_tcsstr_cc(message, buf, _getOptB("ResponseCC", defaultResponseCC)) && (_tcslen(message) == _tcslen(buf))) { bCorrectResponse = TRUE; break; } } } break; case SPAMOTRON_MODE_MATH: if (message == NULL) break; _itot(_getCOptD(hContact, "ResponseMath", -1), buf, 10); if (_tcsstr(message, buf) && (_tcslen(buf) == _tcslen(message))) { bCorrectResponse = TRUE; } break; } if (bCorrectResponse) { _setCOptB(hContact, "Verified", 1); if (_getOptB("HideUnverified", defaultHideUnverified)) db_unset(hContact, "CList", "Hidden"); if (_getOptB("AddPermanently", defaultAddPermanently)) db_unset(hContact, "CList", "NotOnList"); db_unset(hContact, "CList", "Delete"); db_unset(hContact, "CList", "ResponseNum"); if (_getOptB("ReplyOnSuccess", defaultReplyOnSuccess)) { tmp = mir_u2a(_getOptS(buf, buflen, "SuccessResponse", defaultSuccessResponse)); response = mir_utf8encode(tmp); mir_free(tmp); CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)response); mir_free(response); } _notify(hContact, POPUP_APPROVED, TranslateT("Contact %s approved."), NULL); // Resubmit pending authorization request if (_getCOptB(hContact, "AuthEventPending", FALSE)) { DBVARIANT _dbv; TCHAR AuthEventModule[100]; char* szAuthEventModule; if (db_get(hContact, PLUGIN_NAME, "AuthEvent", &_dbv) == 0) { DBEVENTINFO *_dbei = (DBEVENTINFO *)malloc(sizeof(DBEVENTINFO)); if (_dbei != NULL) { memcpy(&_dbei->cbBlob, _dbv.pbVal, sizeof(DWORD)); _dbei->eventType = EVENTTYPE_AUTHREQUEST; _getCOptS(AuthEventModule, 100, hContact, "AuthEventModule", _T("ICQ")); szAuthEventModule = mir_u2a(AuthEventModule); _dbei->szModule = szAuthEventModule; _dbei->timestamp = dbei->timestamp; _dbei->flags = 0; _dbei->cbSize = sizeof(DBEVENTINFO); _dbei->pBlob = _dbv.pbVal + sizeof(DWORD); db_event_add(hContact,_dbei); db_unset(hContact, PLUGIN_NAME, "AuthEvent"); db_unset(hContact, PLUGIN_NAME, "AuthEventPending"); db_unset(hContact, PLUGIN_NAME, "AuthEventModule"); mir_free(szAuthEventModule); free(_dbei); } db_free(&_dbv); } } // User approved, learn from previous messages if (bayesEnabled && _getOptB("BayesAutolearnApproved", defaultBayesAutolearnApproved)) bayes_approve_contact(hContact); // Mark previous messages unread if option set if (_getOptB("KeepBlockedMsg", defaultKeepBlockedMsg) && _getOptB("MarkMsgUnreadOnApproval", defaultMarkMsgUnreadOnApproval) && hContact != NULL) { // We will mark unread all blocked messages for the most recent day MarkUnread(hContact); } return 1; } /*** Check for rejection ***/ // Completely reject if challenge was already sent today for MaxMsgContactCountPerDay times // and the option is turned on. if (isOneDay(dbei->timestamp, _getCOptD(hContact, "MsgSentTime", 0)) && _getOptD("MaxMsgContactCountPerDay", defaultMaxMsgContactCountPerDay) > 0 && _getCOptD(hContact, "MsgSent", 0) >= _getOptD("MaxMsgContactCountPerDay", defaultMaxMsgContactCountPerDay)) { _notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s rejected because it reached a maximum for challenge requests per day."), message); if (bayesEnabled) queue_message(hContact, dbei->timestamp, message); return 1; } // Completely reject if duplicate incoming message found if (_getOptD("MaxSameMsgCountPerDay", defaultMaxSameMsgCountPerDay) > 0 && _getCOptD(hContact, "SameMsgCount", 0) >= _getOptD("MaxSameMsgCountPerDay", defaultMaxSameMsgCountPerDay) && _tcscmp(message, _getCOptS(buf, buflen, hContact, "LastInMsg", _T(""))) == 0) { _notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s rejected because it reached a maximum for same responses per day."), message); if (bayesEnabled) queue_message(hContact, dbei->timestamp, message); return 1; } // Completely reject if incoming message contains any word from DontReplyMsgWordlist option if (_getOptB("DontReplyMsg", defaultDontReplyMsg) && Contains(message, _getOptS(buf, buflen, "DontReplyMsgWordlist", defaultDontReplyMsgWordlist))) { _notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s dropped because it has a word from black list."), message); return 1; } /*** Bayes checks ***/ // Drop if score > spam score if (bayesEnabled && _getOptB("BayesBlockMsg", defaultBayesBlockMsg)) if (get_msg_score(message) >= (double)_getOptD("BayesSpamScore", defaultBayesSpamScore) * SCORE_C) { _notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s dropped because of high spam score."), message); if (bayesEnabled && _getOptB("BayesAutolearnNotApproved", defaultBayesAutolearnNotApproved)) queue_message(hContact, dbei->timestamp, message); return 1; } // Accept if score < ham score if (bayesEnabled && _getOptB("BayesAutoApprove", defaultBayesAutoApprove)) if (get_msg_score(message) <= (double)_getOptD("BayesHamScore", defaultBayesHamScore) * SCORE_C) { _notify(hContact, POPUP_APPROVED, TranslateT("Contact %s approved."), message); _setCOptB(hContact, "Verified", 1); if (_getOptB("HideUnverified", defaultHideUnverified)) db_unset(hContact, "CList", "Hidden"); if (_getOptB("AddPermanently", defaultAddPermanently)) db_unset(hContact, "CList", "NotOnList"); db_unset(hContact, "CList", "Delete"); if (bayesEnabled && _getOptB("BayesAutolearnApproved", defaultBayesAutolearnApproved) && _getOptB("BayesAutolearnAutoApproved", defaultBayesAutolearnAutoApproved)) { queue_message(hContact, dbei->timestamp, message); bayes_approve_contact(hContact); } return 0; } // Accept if event is EVENTTYPE_AUTHREQUEST and ReplyOnAuth is NOT set if (dbei->eventType == EVENTTYPE_AUTHREQUEST && !_getOptB("ReplyOnAuth", defaultReplyOnAuth)) return 0; // Accept if event is EVENTTYPE_MESSAGE and ReplyOnMsg is NOT set if (dbei->eventType == EVENTTYPE_MESSAGE && !_getOptB("ReplyOnMsg", defaultReplyOnMsg)) return 0; /*** Send Challenge ***/ challengeW = (TCHAR *)malloc(maxmsglen*sizeof(TCHAR)); tmpW = (TCHAR *)malloc(maxmsglen*sizeof(TCHAR)); switch (_getOptB("Mode", defaultMode)) { case SPAMOTRON_MODE_PLAIN: if (dbei->eventType == EVENTTYPE_AUTHREQUEST) _getOptS(challengeW, maxmsglen, "AuthChallenge", defaultAuthChallenge); else _getOptS(challengeW, maxmsglen, "Challenge", defaultChallenge); ReplaceVars(challengeW, maxmsglen); tmp = mir_u2a(challengeW); challenge = mir_utf8encode(tmp); mir_free(tmp); CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge); mir_free(challenge); _notify(hContact, POPUP_CHALLENGE, TranslateT("Sending plain challenge to %s."), message); break; case SPAMOTRON_MODE_ROTATE: if (dbei->eventType == EVENTTYPE_AUTHREQUEST) _getOptS(challengeW, maxmsglen, "AuthChallenge", defaultAuthChallenge); else _getOptS(challengeW, maxmsglen, "Challenge", defaultChallenge); _getOptS(buf, buflen, "Response", defaultResponse); if (_getCOptD(hContact, "ResponseNum", 0) >= (unsigned int)(get_response_num(buf)-1)) { _setCOptD(hContact, "ResponseNum", -1); } _setCOptD(hContact, "ResponseNum", _getCOptD(hContact, "ResponseNum", -1) + 1); ReplaceVarsNum(challengeW, maxmsglen, _getCOptD(hContact, "ResponseNum", 0)); tmp = mir_u2a(challengeW); challenge = mir_utf8encode(tmp); mir_free(tmp); CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge); mir_free(challenge); _notify(hContact, POPUP_CHALLENGE, TranslateT("Sending round-robin challenge to %s."), message); break; case SPAMOTRON_MODE_RANDOM: if (dbei->eventType == EVENTTYPE_AUTHREQUEST) _getOptS(challengeW, maxmsglen, "AuthChallenge", defaultAuthChallenge); else _getOptS(challengeW, maxmsglen, "Challenge", defaultChallenge); _getOptS(buf, buflen, "Response", defaultResponse); srand(time(NULL)); _setCOptD(hContact, "ResponseNum", rand() % get_response_num(buf)); ReplaceVarsNum(challengeW, maxmsglen, _getCOptD(hContact, "ResponseNum", 0)); tmp = mir_u2a(challengeW); challenge = mir_utf8encode(tmp); mir_free(tmp); CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge); mir_free(challenge); _notify(hContact, POPUP_CHALLENGE, TranslateT("Sending random challenge to %s."), message); break; case SPAMOTRON_MODE_MATH: a = (rand() % 10) + 1; b = (rand() % 10) + 1; mir_sntprintf(mexpr, sizeof(mexpr), _T("%d + %d"), a, b); if (dbei->eventType == EVENTTYPE_AUTHREQUEST) _getOptS(challengeW, maxmsglen, "AuthChallengeMath", defaultAuthChallengeMath); else _getOptS(challengeW, maxmsglen, "ChallengeMath", defaultChallengeMath); ReplaceVar(challengeW, maxmsglen, _T("%mathexpr%"), mexpr); _setCOptD(hContact, "ResponseMath", a + b); tmp = mir_u2a(challengeW); challenge = mir_utf8encode(tmp); mir_free(tmp); CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge); mir_free(challenge); _notify(hContact, POPUP_CHALLENGE, TranslateT("Sending math expression challenge to %s."), message); break; } free(challengeW); free(tmpW); // As a workaround for temporary NotOnList contact not being deleted from server-side list // (which was added by the ICQ server itself upon first outgoing challenge request message) // we need to set Delete setting, so that contacts gets deleted on next restart/connect. db_set_b(hContact, "CList", "Delete", 1); // Queue user message in Bayes db if (bayesEnabled && message != NULL) queue_message(hContact, dbei->timestamp, message); /*** Do any post-send procedures we need to do ***/ // Increment MsgSent if it was sent the same day. Otherwise set it to 1. if (isOneDay(dbei->timestamp, _getCOptD(hContact, "MsgSentTime",0))) _setCOptD(hContact, "MsgSent", _getCOptD(hContact, "MsgSent", 0)+1); else _setCOptD(hContact, "MsgSent", 1); _setCOptD(hContact, "MsgSentTime", dbei->timestamp); // Save Last Msg and update SameMsgCount if (message != NULL) { if (_tcscmp(_getCOptS(buf, buflen, hContact, "LastInMsg", _T("")), message) == 0) _setCOptD(hContact, "SameMsgCount", 1+_getCOptD(hContact, "SameMsgCount", 0)); else _setCOptD(hContact, "SameMsgCount", 1); _setCOptTS(hContact, "LastInMsg", message); } if (message != NULL) mir_free(message); // Finally silently save the message to contact history if corresponding option is set if (_getOptB("KeepBlockedMsg", defaultKeepBlockedMsg)) { if (dbei->eventType == EVENTTYPE_AUTHREQUEST) { // Save the request to database so that it can be automatically submitted on user approval PBYTE eventdata = (PBYTE)malloc(sizeof(DWORD) + dbei->cbBlob); if (eventdata != NULL && dbei->cbBlob > 0) { memcpy(eventdata, &dbei->cbBlob, sizeof(DWORD)); memcpy(eventdata + sizeof(DWORD), dbei->pBlob, dbei->cbBlob); db_set_blob(hContact, PLUGIN_NAME, "AuthEvent", eventdata, sizeof(DWORD) + dbei->cbBlob); _setCOptS(hContact, "AuthEventModule", dbei->szModule); _setCOptB(hContact, "AuthEventPending", TRUE); free(eventdata); } } else { if (_getOptB("MarkMsgUnreadOnApproval", defaultMarkMsgUnreadOnApproval)) { DBVARIANT _dbv; DWORD dbei_size = 3*sizeof(DWORD) + sizeof(WORD) + dbei->cbBlob + (DWORD)strlen(dbei->szModule)+1; PBYTE eventdata = (PBYTE)malloc(dbei_size); PBYTE pos = eventdata; if (eventdata != NULL && dbei->cbBlob > 0) { if (db_get(hContact, PLUGIN_NAME, "LastMsgEvents", &_dbv) == 0) { eventdata = (PBYTE)realloc(eventdata, dbei_size + _dbv.cpbVal); pos = eventdata; memcpy(eventdata, _dbv.pbVal, _dbv.cpbVal); pos += _dbv.cpbVal; db_free(&_dbv); } memcpy(pos, &dbei->eventType, sizeof(WORD)); memcpy(pos+sizeof(WORD), &dbei->flags, sizeof(DWORD)); memcpy(pos+sizeof(WORD)+sizeof(DWORD), &dbei->timestamp, sizeof(DWORD)); memcpy(pos+sizeof(WORD)+sizeof(DWORD)*2, dbei->szModule, strlen(dbei->szModule)+1); memcpy(pos+sizeof(WORD)+sizeof(DWORD)*2+strlen(dbei->szModule)+1, &dbei->cbBlob, sizeof(DWORD)); memcpy(pos+sizeof(WORD)+sizeof(DWORD)*3+strlen(dbei->szModule)+1, dbei->pBlob, dbei->cbBlob); db_set_blob(hContact, PLUGIN_NAME, "LastMsgEvents", eventdata, (pos - eventdata) + dbei_size); free(eventdata); } } else { dbei->flags |= DBEF_READ; db_event_add(hContact, dbei); } } } return 1; }
MIRANDA_HOOK_EVENT(ME_DB_EVENT_FILTER_ADD, w, l) { MCONTACT hContact = (MCONTACT)w; if (!l) //fix potential DEP crash return 0; DBEVENTINFO * dbei = (DBEVENTINFO*)l; // if event is in protocol that is not despammed if (!ProtoInList(dbei->szModule)) { // ...let the event go its way return 0; } //do not check excluded contact if (db_get_b(hContact, pluginName, "Answered", 0)) return 0; if (db_get_b(hContact, pluginName, "Excluded", 0)) { if (!db_get_b(hContact, "CList", "NotOnList", 0)) db_unset(hContact, pluginName, "Excluded"); return 0; } //we want block not only messages, i seen many types other eventtype flood if (dbei->flags & DBEF_READ) // ...let the event go its way return 0; //mark contact which we trying to contact for exclude from check if ((dbei->flags & DBEF_SENT) && db_get_b(hContact, "CList", "NotOnList", 0) && (!gbMaxQuestCount || db_get_dw(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount) && gbExclude) { db_set_b(hContact, pluginName, "Excluded", 1); return 0; } // if message is from known or marked Answered contact if (!db_get_b(hContact, "CList", "NotOnList", 0)) // ...let the event go its way return 0; // if message is corrupted or empty it cannot be an answer. if (!dbei->cbBlob || !dbei->pBlob) // reject processing of the event return 1; tstring message; if (dbei->flags & DBEF_UTF) { wchar_t* msg_u; char* msg_a = mir_strdup((char*)dbei->pBlob); mir_utf8decode(msg_a, &msg_u); message = msg_u; } else message = mir_a2u((char*)(dbei->pBlob)); // if message contains right answer... boost::algorithm::erase_all(message, "\r"); boost::algorithm::erase_all(message, "\n"); bool bSendMsg = true; if (gbInvisDisable) { if (CallProtoService(dbei->szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE) bSendMsg = false; else if (db_get_w(hContact, dbei->szModule, "ApparentMode", 0) == ID_STATUS_OFFLINE) bSendMsg = false; //is it useful ? } bool answered = false; if (gbMathExpression) { if (boost::algorithm::all(message, boost::is_digit())) { int num = _ttoi(message.c_str()); int math_answer = db_get_dw(hContact, pluginName, "MathAnswer", 0); if (num && math_answer) answered = (num == math_answer); } } else if (!gbRegexMatch) answered = gbCaseInsensitive ? (!Stricmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str()))) : (!mir_tstrcmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str()))); else { if (gbCaseInsensitive) { std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message)); boost::algorithm::to_upper(check); boost::algorithm::to_upper(msg); boost::regex expr(check); answered = boost::regex_search(msg.begin(), msg.end(), expr); } else { std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message)); boost::regex expr(check); answered = boost::regex_search(msg.begin(), msg.end(), expr); } } if (answered) { // unhide contact db_unset(hContact, "CList", "Hidden"); db_unset(hContact, pluginName, "MathAnswer"); // mark contact as Answered db_set_b(hContact, pluginName, "Answered", 1); //add contact permanently if (gbAddPermanent) //do not use this ) db_unset(hContact, "CList", "NotOnList"); // send congratulation if (bSendMsg) { tstring prot = DBGetContactSettingStringPAN(NULL, dbei->szModule, "AM_BaseProto", _T("")); // for notICQ protocols or disable auto auth. reqwest if ((Stricmp(_T("ICQ"), prot.c_str())) || (!gbAutoReqAuth)) { char * buf = mir_utf8encodeW(variables_parse(gbCongratulation, hContact).c_str()); CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)buf); mir_free(buf); } // Note: For ANSI can be not work if (!Stricmp(_T("ICQ"), prot.c_str())) { // grand auth. if (gbAutoAuth) CallProtoService(dbei->szModule, "/GrantAuth", w, 0); // add contact to server list and local group if (gbAutoAddToServerList) { db_set_ws(hContact, "CList", "Group", gbAutoAuthGroup.c_str()); CallProtoService(dbei->szModule, "/AddServerContact", w, 0); db_unset(hContact, "CList", "NotOnList"); }; // auto auth. reqwest with send congratulation if (gbAutoReqAuth) CallContactService(hContact, PSS_AUTHREQUEST, 0, (LPARAM)variables_parse(gbCongratulation, hContact).c_str()); } } return 0; } // URL contains check bSendMsg = (bSendMsg && gbIgnoreURL) ? (!IsUrlContains((TCHAR *)message.c_str())) : bSendMsg; // if message message does not contain infintite talk protection prefix // and question count for this contact is less then maximum if (bSendMsg) { if ((!gbInfTalkProtection || tstring::npos == message.find(_T("StopSpam automatic message:\r\n"))) && (!gbMaxQuestCount || db_get_dw(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount)) { // send question tstring q; if (gbInfTalkProtection) q += _T("StopSpam automatic message:\r\n"); if (gbMathExpression) { //parse math expression in question tstring tmp_question = gbQuestion; std::list<int> args; std::list<TCHAR> actions; tstring::size_type p1 = gbQuestion.find(_T("X")), p2 = 0; const tstring expr_chars = _T("X+-/*"), expr_acts = _T("+-/*"); while (p1 < gbQuestion.length() && p1 != tstring::npos && expr_chars.find(gbQuestion[p1]) != tstring::npos) { std::string arg; p2 = p1; for (p1 = gbQuestion.find(_T("X"), p1); (p1 < gbQuestion.length()) && (gbQuestion[p1] == L'X'); ++p1) arg += get_random_num(1); tmp_question.replace(p2, arg.size(), toUTF16(arg)); args.push_back(atoi(arg.c_str())); if ((p1 < gbQuestion.length()) && (p1 != tstring::npos) && (expr_acts.find(gbQuestion[p1]) != tstring::npos)) actions.push_back(gbQuestion[p1]); ++p1; } int math_answer = 0; math_answer = args.front(); args.pop_front(); while (!args.empty()) { if (!actions.empty()) { switch (actions.front()) { case _T('+'): { math_answer += args.front(); args.pop_front(); } break; case _T('-'): { math_answer -= args.front(); args.pop_front(); } break; case _T('/'): { math_answer /= args.front(); args.pop_front(); } break; case _T('*'): { math_answer *= args.front(); args.pop_front(); } break; } actions.pop_front(); } else break; } db_set_dw(hContact, pluginName, "MathAnswer", math_answer); q += variables_parse(tmp_question, hContact); } else q += variables_parse(gbQuestion, hContact); CallContactService(hContact, PSS_MESSAGE, 0, ptrA(mir_utf8encodeW(q.c_str()))); // increment question count DWORD questCount = db_get_dw(hContact, pluginName, "QuestionCount", 0); db_set_dw(hContact, pluginName, "QuestionCount", questCount + 1); } else { if (gbIgnoreContacts) db_set_dw(hContact, "Ignore", "Mask1", 0x0000007F); } } if (gbHideContacts) db_set_b(hContact, "CList", "Hidden", 1); if (gbSpecialGroup) db_set_ws(hContact, "CList", "Group", gbSpammersGroup.c_str()); db_set_b(hContact, "CList", "NotOnList", 1); // save first message from contact if (db_get_dw(hContact, pluginName, "QuestionCount", 0) < 2) { dbei->flags |= DBEF_READ; db_event_add(hContact, dbei); }; // reject processing of the event LogSpamToFile(hContact, message); return 1; }
static bool VerifyCertificate(SslHandle *ssl, PCSTR pszServerName, DWORD dwCertFlags) { if (!g_Crypt.CertGetCertificateChain) return true; static LPSTR rgszUsages[] = { szOID_PKIX_KP_SERVER_AUTH, szOID_SERVER_GATED_CRYPTO, szOID_SGC_NETSCAPE }; CERT_CHAIN_PARA ChainPara = { 0 }; HTTPSPolicyCallbackData polHttps = { 0 }; CERT_CHAIN_POLICY_PARA PolicyPara = { 0 }; CERT_CHAIN_POLICY_STATUS PolicyStatus = { 0 }; PCCERT_CHAIN_CONTEXT pChainContext = NULL; PCCERT_CONTEXT pServerCert = NULL; DWORD scRet; PWSTR pwszServerName = mir_a2u(pszServerName); pServerCert = SSL_CertChainToCryptAnchor(ssl->session); if (pServerCert == NULL) { scRet = SEC_E_WRONG_PRINCIPAL; goto cleanup; } ChainPara.cbSize = sizeof(ChainPara); ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; ChainPara.RequestedUsage.Usage.cUsageIdentifier = _countof(rgszUsages); ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgszUsages; if (!g_Crypt.CertGetCertificateChain(NULL, pServerCert, NULL, pServerCert->hCertStore, &ChainPara, 0, NULL, &pChainContext)) { scRet = GetLastError(); goto cleanup; } polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData); polHttps.dwAuthType = AUTHTYPE_SERVER; polHttps.fdwChecks = dwCertFlags; polHttps.pwszServerName = pwszServerName; PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.pvExtraPolicyPara = &polHttps; PolicyStatus.cbSize = sizeof(PolicyStatus); if (!g_Crypt.CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, pChainContext, &PolicyPara, &PolicyStatus)) { scRet = GetLastError(); goto cleanup; } if (PolicyStatus.dwError) { scRet = PolicyStatus.dwError; goto cleanup; } scRet = SEC_E_OK; cleanup: if (pChainContext) g_Crypt.CertFreeCertificateChain(pChainContext); if (pServerCert) g_Crypt.CertFreeCertificateContext(pServerCert); mir_free(pwszServerName); ReportSslError(scRet, __LINE__, true); return scRet == SEC_E_OK; }
MIRANDA_HOOK_EVENT(ME_DB_EVENT_FILTER_ADD, w, l) { MCONTACT hContact = (MCONTACT)w; DBEVENTINFO *dbei = (DBEVENTINFO*)l; if (dbei == NULL) //fix potential DEP crash return 0; // if event is in protocol that is not despammed if (plSets->ProtoDisabled(dbei->szModule)) // ...let the event go its way return 0; // if event is not a message, or if the message has been read or sent... if (dbei->flags & DBEF_SENT || dbei->flags & DBEF_READ || dbei->eventType != EVENTTYPE_MESSAGE) // ...let the event go its way return 0; // if message is from known or marked Answered contact if (db_get_b(hContact, pluginName, answeredSetting, 0)) // ...let the event go its way return 0; // checking if message from self-added contact //Contact in Not in list icq group if (!db_get_b(hContact, "CList", "NotOnList", 0) && db_get_w(hContact, dbei->szModule, "SrvGroupId", -1) != 1) return 0; //if I sent message to this contact if (IsExistMyMessage(hContact)) return 0; // if message is corrupted or empty it cannot be an answer. if (!dbei->cbBlob || !dbei->pBlob) // reject processing of the event return 1; tstring message; if (dbei->flags & DBEF_UTF){ WCHAR* msg_u = mir_utf8decodeW((char*)dbei->pBlob); message = msg_u; mir_free(msg_u); } else { WCHAR* msg_u = mir_a2u((char*)(dbei->pBlob)); message = msg_u; mir_free(msg_u); } // if message equal right answer... tstring answers = variables_parse(plSets->Answer.Get(), hContact); answers.append(plSets->AnswSplitString.Get()); tstring::size_type pos = 0; tstring::size_type prev_pos = 0; while ((pos = answers.find(plSets->AnswSplitString.Get(), pos)) != tstring::npos) { // get one of answers and trim witespace chars tstring answer = trim(answers.substr(prev_pos, pos - prev_pos)); // if answer not empty if (answer.length() > 0) { // if message equal right answer... if (plSets->AnswNotCaseSens.Get() ? !mir_tstrcmpi(message.c_str(), answer.c_str()) : !mir_tstrcmp(message.c_str(), answer.c_str())) { // unhide contact db_unset(hContact, "CList", "Hidden"); // mark contact as Answered db_set_b(hContact, pluginName, answeredSetting, 1); //add contact permanently if (plSets->AddPermanent.Get()) db_unset(hContact, "CList", "NotOnList"); // send congratulation char * buf = mir_utf8encodeW(variables_parse(plSets->Congratulation.Get(), hContact).c_str()); CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)buf); mir_free(buf); // process the event return 1; } } prev_pos = ++pos; } // if message message does not contain infintite talk protection prefix // and question count for this contact is less then maximum if ((!plSets->InfTalkProtection.Get() || tstring::npos == message.find(infTalkProtPrefix)) && (!plSets->MaxQuestCount.Get() || db_get_dw(hContact, pluginName, questCountSetting, 0) < plSets->MaxQuestCount.Get())) { // send question tstring q = infTalkProtPrefix + variables_parse((tstring)(plSets->Question), hContact); char * buf = mir_utf8encodeW(q.c_str()); CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)buf); mir_free(buf); // increment question count DWORD questCount = db_get_dw(hContact, pluginName, questCountSetting, 0); db_set_dw(hContact, pluginName, questCountSetting, questCount + 1); } // hide contact from contact list db_set_b(hContact, "CList", "NotOnList", 1); db_set_b(hContact, "CList", "Hidden", 1); // save message from contact dbei->flags |= DBEF_READ; db_event_add(hContact, dbei); // reject processing of the event return 1; }
static INT_PTR GetContactInfo(WPARAM, LPARAM lParam) { DBVARIANT dbv; CONTACTINFO *ci = (CONTACTINFO*)lParam; if (ci==NULL) return 1; if (ci->szProto==NULL) ci->szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEACCOUNT,(WPARAM)ci->hContact,0); if (ci->szProto==NULL) return 1; ci->type = 0; switch(ci->dwFlag & 0x7F) { case CNF_FIRSTNAME: return ProcessDatabaseValueDefault( ci, "FirstName" ); case CNF_LASTNAME: return ProcessDatabaseValueDefault( ci, "LastName" ); case CNF_NICK: return ProcessDatabaseValueDefault( ci, "Nick" ); case CNF_EMAIL: return ProcessDatabaseValueDefault( ci, "e-mail" ); case CNF_CITY: return ProcessDatabaseValueDefault( ci, "City" ); case CNF_STATE: return ProcessDatabaseValueDefault( ci, "State" ); case CNF_PHONE: return ProcessDatabaseValueDefault( ci, "Phone" ); case CNF_HOMEPAGE: return ProcessDatabaseValueDefault( ci, "Homepage" ); case CNF_ABOUT: return ProcessDatabaseValueDefault( ci, "About" ); case CNF_AGE: return ProcessDatabaseValueDefault( ci, "Age" ); case CNF_GENDER: return ProcessDatabaseValueDefault( ci, "Gender" ); case CNF_FAX: return ProcessDatabaseValueDefault( ci, "Fax" ); case CNF_CELLULAR: return ProcessDatabaseValueDefault( ci, "Cellular" ); case CNF_BIRTHDAY: return ProcessDatabaseValueDefault( ci, "BirthDay" ); case CNF_BIRTHMONTH: return ProcessDatabaseValueDefault( ci, "BirthMonth" ); case CNF_BIRTHYEAR: return ProcessDatabaseValueDefault( ci, "BirthYear" ); case CNF_STREET: return ProcessDatabaseValueDefault( ci, "Street" ); case CNF_ZIP: return ProcessDatabaseValueDefault( ci, "ZIP" ); case CNF_LANGUAGE1: return ProcessDatabaseValueDefault( ci, "Language1" ); case CNF_LANGUAGE2: return ProcessDatabaseValueDefault( ci, "Language2" ); case CNF_LANGUAGE3: return ProcessDatabaseValueDefault( ci, "Language3" ); case CNF_CONAME: return ProcessDatabaseValueDefault( ci, "Company" ); case CNF_CODEPT: return ProcessDatabaseValueDefault( ci, "CompanyDepartment" ); case CNF_COPOSITION: return ProcessDatabaseValueDefault( ci, "CompanyPosition" ); case CNF_COSTREET: return ProcessDatabaseValueDefault( ci, "CompanyStreet" ); case CNF_COCITY: return ProcessDatabaseValueDefault( ci, "CompanyCity" ); case CNF_COSTATE: return ProcessDatabaseValueDefault( ci, "CompanyState" ); case CNF_COZIP: return ProcessDatabaseValueDefault( ci, "CompanyZIP" ); case CNF_COHOMEPAGE: return ProcessDatabaseValueDefault( ci, "CompanyHomepage" ); case CNF_CUSTOMNICK: { char* saveProto = ci->szProto; ci->szProto = "CList"; if ( ci->hContact != NULL && !ProcessDatabaseValueDefault( ci, "MyHandle" )) { ci->szProto = saveProto; return 0; } ci->szProto = saveProto; break; } case CNF_COUNTRY: case CNF_COCOUNTRY: if ( !GetDatabaseString( ci, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "CountryName" : "CompanyCountryName", &dbv )) return 0; if ( !DBGetContactSetting( ci->hContact, ci->szProto, (ci->dwFlag & 0x7F)==CNF_COUNTRY ? "Country" : "CompanyCountry", &dbv )) { if ( dbv.type == DBVT_WORD ) { int i,countryCount; struct CountryListEntry *countries; CallService(MS_UTILS_GETCOUNTRYLIST,(WPARAM)&countryCount,(LPARAM)&countries); for(i=0;i<countryCount;i++) { if(countries[i].id!=dbv.wVal) continue; if ( ci->dwFlag & CNF_UNICODE ) { int cbLen = MultiByteToWideChar( CP_ACP, 0, ( LPCSTR )countries[i].szName, -1, NULL, 0 ); WCHAR* buf = ( WCHAR* )mir_alloc( sizeof( WCHAR )*(cbLen+1) ); if ( buf != NULL ) MultiByteToWideChar( CP_ACP, 0, ( LPCSTR )countries[i].szName, -1, buf, cbLen ); ci->pszVal = ( TCHAR* )buf; } else ci->pszVal = ( TCHAR* )mir_strdup(countries[i].szName); ci->type = CNFT_ASCIIZ; DBFreeVariant(&dbv); return 0; } } else return ProcessDatabaseValueDefault( ci, (ci->dwFlag & 0x7F)==CNF_COUNTRY ? "Country" : "CompanyCountry" ); DBFreeVariant(&dbv); } break; case CNF_FIRSTLAST: if( !GetDatabaseString( ci, "FirstName", &dbv )) { DBVARIANT dbv2; if(!GetDatabaseString(ci,"LastName",&dbv2)) { ci->type = CNFT_ASCIIZ; if ( ci->dwFlag & CNF_UNICODE ) { size_t len = wcslen(dbv.pwszVal) + wcslen(dbv2.pwszVal) + 2; WCHAR* buf = ( WCHAR* )mir_alloc( sizeof( WCHAR )*len ); if ( buf != NULL ) wcscat( wcscat( wcscpy( buf, dbv.pwszVal ), L" " ), dbv2.pwszVal ); ci->pszVal = ( TCHAR* )buf; } else { size_t len = strlen(dbv.pszVal) + strlen(dbv2.pszVal) + 2; char* buf = ( char* )mir_alloc( len ); if ( buf != NULL ) strcat( strcat( strcpy( buf, dbv.pszVal ), " " ), dbv2.pszVal ); ci->pszVal = ( TCHAR* )buf; } DBFreeVariant( &dbv ); DBFreeVariant( &dbv2 ); return 0; } DBFreeVariant( &dbv ); } break; case CNF_UNIQUEID: { char *uid = (char*)CallProtoService(ci->szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); if ((INT_PTR)uid!=CALLSERVICE_NOTFOUND&&uid) if (!ProcessDatabaseValueDefault(ci,uid)) return 0; break; } case CNF_DISPLAYUID: { if (!ProcessDatabaseValueDefault(ci, "display_uid")) return 0; char *uid = (char*)CallProtoService(ci->szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); if ((INT_PTR)uid!=CALLSERVICE_NOTFOUND&&uid) if (!ProcessDatabaseValueDefault(ci,uid)) return 0; break; } case CNF_DISPLAYNC: case CNF_DISPLAY: { int i; for( i=0; i < NAMEORDERCOUNT; i++ ) { switch(nameOrder[i]) { case 0: // custom name { // make sure we aren't in CNF_DISPLAYNC mode // don't get custom name for NULL contact char* saveProto = ci->szProto; ci->szProto = "CList"; if (ci->hContact!=NULL && (ci->dwFlag&0x7F)==CNF_DISPLAY && !ProcessDatabaseValueDefault(ci,"MyHandle")) { ci->szProto = saveProto; return 0; } ci->szProto = saveProto; break; } case 1: if ( !ProcessDatabaseValueDefault( ci, "Nick" )) // nick return 0; break; case 2: if ( !ProcessDatabaseValueDefault( ci, "FirstName" )) // First Name return 0; break; case 3: if ( !ProcessDatabaseValueDefault( ci, "e-mail" )) // E-mail return 0; break; case 4: if ( !ProcessDatabaseValueDefault( ci, "LastName" )) // Last Name return 0; break; case 5: // Unique id { // protocol must define a PFLAG_UNIQUEIDSETTING char *uid = (char*)CallProtoService(ci->szProto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); if ((INT_PTR)uid!=CALLSERVICE_NOTFOUND&&uid) { if (!GetDatabaseString(ci,uid,&dbv)) { if ( dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD ) { long value = (dbv.type == DBVT_BYTE) ? dbv.bVal:(dbv.type==DBVT_WORD ? dbv.wVal : dbv.dVal); if ( ci->dwFlag & CNF_UNICODE ) { WCHAR buf[ 40 ]; _ltow( value, buf, 10 ); ci->pszVal = ( TCHAR* )mir_wstrdup( buf ); } else { char buf[ 40 ]; _ltoa( value, buf, 10 ); ci->pszVal = ( TCHAR* )mir_strdup(buf); } ci->type = CNFT_ASCIIZ; return 0; } if (dbv.type == DBVT_ASCIIZ && !(ci->dwFlag & CNF_UNICODE)) { ci->type = CNFT_ASCIIZ; ci->pszVal = dbv.ptszVal; return 0; } if (dbv.type == DBVT_WCHAR && (ci->dwFlag & CNF_UNICODE)) { ci->type = CNFT_ASCIIZ; ci->pszVal = dbv.ptszVal; return 0; } } } break; } case 6: // first + last name if(!GetDatabaseString(ci,"FirstName",&dbv)) { DBVARIANT dbv2; if(!GetDatabaseString(ci,"LastName",&dbv2)) { ci->type = CNFT_ASCIIZ; if ( ci->dwFlag & CNF_UNICODE ) { size_t len = wcslen(dbv.pwszVal) + wcslen(dbv2.pwszVal) + 2; WCHAR* buf = ( WCHAR* )mir_alloc( sizeof( WCHAR )*len ); if ( buf != NULL ) wcscat( wcscat( wcscpy( buf, dbv.pwszVal ), L" " ), dbv2.pwszVal ); ci->pszVal = ( TCHAR* )buf; } else { size_t len = strlen(dbv.pszVal) + strlen(dbv2.pszVal) + 2; char* buf = ( char* )mir_alloc( len ); if ( buf != NULL ) strcat( strcat( strcpy( buf, dbv.pszVal ), " " ), dbv2.pszVal ); ci->pszVal = ( TCHAR* )buf; } DBFreeVariant( &dbv ); DBFreeVariant( &dbv2 ); return 0; } DBFreeVariant( &dbv ); } break; case 7: if ( ci->dwFlag & CNF_UNICODE ) ci->pszVal = ( TCHAR* )mir_wstrdup( TranslateW( L"'(Unknown Contact)'" )); else ci->pszVal = ( TCHAR* )mir_strdup( Translate("'(Unknown Contact)'")); ci->type = CNFT_ASCIIZ; return 0; } } } break; case CNF_TIMEZONE: { HANDLE hTz = tmi.createByContact(ci->hContact, TZF_KNOWNONLY); if (hTz) { LPTIME_ZONE_INFORMATION tzi = tmi.getTzi(hTz); int offset = tzi->Bias + tzi->StandardBias; char str[80]; mir_snprintf(str, SIZEOF(str), offset ? "UTC%+d:%02d" : "UTC", offset / -60, abs(offset % 60)); ci->pszVal = ci->dwFlag & CNF_UNICODE ? (TCHAR*)mir_a2u(str) : (TCHAR*)mir_strdup(str); ci->type = CNFT_ASCIIZ; return 0; } break; } case CNF_MYNOTES: { char* saveProto = ci->szProto; ci->szProto = "UserInfo"; if (!ProcessDatabaseValueDefault(ci,"MyNotes")) { ci->szProto = saveProto; return 0; } ci->szProto = saveProto; break; } } return 1; }