void sttGenerateRSA(LPVOID) { char priv_key[4096]; int priv_len; char pub_key[4096]; int pub_len; mir_exp->rsa_gen_keypair(CPP_MODE_RSA_4096); mir_exp->rsa_get_keypair(CPP_MODE_RSA_4096, (PBYTE)&priv_key, &priv_len, (PBYTE)&pub_key, &pub_len); db_set_blob(NULL, MODULENAME, "rsa_priv", priv_key, priv_len); db_set_blob(NULL, MODULENAME, "rsa_pub", pub_key, pub_len); rsa_4096 = 1; }
// calculate secret key BOOL CalculateKeyX(pUinKey ptr,MCONTACT hContact) { int agr = cpp_calc_keyx(ptr->cntx); if (agr) { // do this only if key exchanged is ok // we use a 192bit key int keysize = cpp_size_keyx(); PBYTE buffer = (PBYTE) alloca(keysize); // buffer for hash // store key cpp_get_keyx(ptr->cntx,buffer); // store key in database db_set_blob(hContact, MODULENAME, "offlineKey", buffer, keysize); // store timeout of key in database (2 days) db_set_dw(hContact, MODULENAME, "offlineKeyTimeout", gettime()+(60*60*24*db_get_w(0,MODULENAME,"okt",2))); // key exchange is finished showPopupEC(ptr->hContact); } else { // agree value problem showPopup(sim002,hContact,g_hPOP[POP_PU_DIS],0); } return agr != 0; }
int WriteBlobFromString(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue, int len) { int j = 0, i = 0; BYTE b; int tmp, res = 0; BYTE *data = (BYTE*)mir_alloc(2 + len / 2); if (!data) return 0; while (j < len) { b = szValue[j]; if ((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')) { if (sscanf(&szValue[j], "%02X", &tmp) == 1) { data[i++] = (BYTE)(tmp & 0xFF); j++; } } j++; } if (i) res = !db_set_blob(hContact, szModule, szSetting, data, (WORD)i); mir_free(data); return res; }
void CToxProto::OnGotFriendAvatarData(Tox *tox, int32_t number, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t length, void *arg) { CToxProto *proto = (CToxProto*)arg; MCONTACT hContact = proto->FindContact(number); if (hContact) { db_set_blob(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, hash, TOX_HASH_LENGTH); std::tstring path = proto->GetAvatarFilePath(hContact); FILE *hFile = _tfopen(path.c_str(), L"wb"); if (hFile) { if (fwrite(data, sizeof(uint8_t), length, hFile) == length) { PROTO_AVATAR_INFORMATIONW pai = { sizeof(pai) }; pai.format = PA_FORMAT_PNG; pai.hContact = hContact; _tcscpy(pai.filename, path.c_str()); proto->ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0); } fclose(hFile); } } }
int WriteBlobFromString(HANDLE hContact,const char *szModule,const char *szSetting, const char *szValue, int len) { int j=0, i = 0; BYTE *data = NULL; BYTE b; int tmp; if (!(data = (BYTE *)_alloca(2 + len / 2))) { msg(Translate("Couldn't allocate enough memory!"), modFullname); return 0; } while (j < len) { b = szValue[j]; if ((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')) { if (sscanf(&szValue[j], "%02X", &tmp) == 1) { data[i++] = (BYTE)tmp; j++; } } j++; } if (i) return db_set_blob(hContact, szModule, szSetting, data, (WORD)i); return 0; }
// pData must always be Unicode data, registry supports Unicode even on Win95 static void WriteDbBackupData(const char *pszSetting,DWORD dwType,BYTE *pData,DWORD cbData) { size_t cbLen = cbData + sizeof(DWORD); PBYTE buf = (PBYTE)mir_alloc(cbLen); if (buf) { *(DWORD*)buf = dwType; memcpy(buf+sizeof(DWORD), pData, cbData); db_set_blob(NULL, "AssocMgr", pszSetting, buf, (unsigned)cbLen); mir_free(buf); } }
void CTelegramProto::SaveState() { int x[4]; x[0] = TLS->pts; x[1] = TLS->qts; x[2] = TLS->seq; x[3] = TLS->date; db_set_blob(0, m_szModuleName, "TGL_STATE", &x, sizeof(x)); }
int __cdecl rsa_check_pub(HANDLE context, PBYTE pub, int pubLen, PBYTE sig, int sigLen) { int v = 0, k = 0; pUinKey ptr = getUinCtx(context); if (!ptr) return 0; LPSTR cnm = (LPSTR)mir_alloc(NAMSIZE); getContactNameA(ptr->hContact, cnm); LPSTR uin = (LPSTR)mir_alloc(KEYSIZE); getContactUinA(ptr->hContact, uin); LPSTR msg = (LPSTR)mir_alloc(MSGSIZE); LPSTR sha = mir_strdup(to_hex(sig, sigLen)); LPSTR sha_old = NULL; Sent_NetLog("rsa_check_pub: %s %s %s", cnm, uin, sha); DBVARIANT dbv; dbv.type = DBVT_BLOB; if (db_get(ptr->hContact, MODULENAME, "rsa_pub", &dbv) == 0) { k = 1; PBYTE buf = (PBYTE)alloca(sigLen); int len; mir_exp->rsa_get_hash((PBYTE)dbv.pbVal, dbv.cpbVal, (PBYTE)buf, &len); sha_old = mir_strdup(to_hex(buf, len)); db_free(&dbv); } if (bAAK) { if (k) mir_snprintf(msg, MSGSIZE, Translate(sim523), cnm, uin, sha, sha_old); else mir_snprintf(msg, MSGSIZE, Translate(sim521), cnm, uin, sha); showPopupKRmsg(ptr->hContact, msg); HistoryLog(ptr->hContact, msg); v = 1; #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("rsa_check_pub: auto accepted"); #endif } else { if (k) mir_snprintf(msg, MSGSIZE, Translate(sim522), cnm, sha, sha_old); else mir_snprintf(msg, MSGSIZE, Translate(sim520), cnm, sha); v = (msgbox(0, msg, MODULENAME, MB_YESNO | MB_ICONQUESTION) == IDYES); #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("rsa_check_pub: manual accepted %d", v); #endif } if (v) { db_set_blob(ptr->hContact, MODULENAME, "rsa_pub", pub, pubLen); ptr->keyLoaded = true; } mir_free(cnm); mir_free(uin); mir_free(msg); mir_free(sha); SAFE_FREE(sha_old); return v; }
virtual void OnApply() { TVITEMEX tvi; tvi.hItem = m_nameOrder.GetRoot(); int i = 0; while (tvi.hItem != NULL) { tvi.mask = TVIF_PARAM | TVIF_HANDLE; m_nameOrder.GetItem(&tvi); nameOrder[i++] = (BYTE)tvi.lParam; tvi.hItem = m_nameOrder.GetNextSibling(tvi.hItem); } db_set_blob(NULL, "Contact", "NameOrder", nameOrder, _countof(nameOrderDescr)); CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)INVALID_HANDLE_VALUE, 0); }
void CToxProto::OnGotFriendAvatarData(AvatarTransferParam *transfer) { db_set_blob(transfer->pfts.hContact, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, transfer->hash, TOX_HASH_LENGTH); PROTO_AVATAR_INFORMATION ai = { 0 }; ai.format = PA_FORMAT_PNG; ai.hContact = transfer->pfts.hContact; mir_tstrcpy(ai.filename, transfer->pfts.tszCurrentFile); fclose(transfer->hFile); transfer->hFile = NULL; ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&ai, 0); transfers.Remove(transfer); }
INT_PTR __cdecl Service_PGPsetKey(WPARAM wParam, LPARAM lParam) { BOOL del = true; if (bPGPloaded) { if (bPGPkeyrings) { char szKeyID[128]; szKeyID[0] = '\0'; PVOID KeyID = pgp_select_keyid(GetForegroundWindow(), szKeyID); if (szKeyID[0]) { db_unset(wParam, MODULENAME, "pgp"); db_set_blob(wParam, MODULENAME, "pgp", KeyID, pgp_size_keyid()); db_set_b(wParam, MODULENAME, "pgp_mode", 0); db_set_s(wParam, MODULENAME, "pgp_abbr", szKeyID); del = false; } } else if (bPGPprivkey) { char KeyPath[MAX_PATH]; KeyPath[0] = '\0'; if (ShowSelectKeyDlg(0, KeyPath)) { char *publ = LoadKeys(KeyPath, false); if (publ) { db_unset(wParam, MODULENAME, "pgp"); db_set_s(wParam, MODULENAME, "pgp", publ); db_set_b(wParam, MODULENAME, "pgp_mode", 1); db_set_s(wParam, MODULENAME, "pgp_abbr", "(binary)"); mir_free(publ); del = false; } } } } if (del) Service_PGPdelKey(wParam, lParam); else { pUinKey ptr = getUinKey(wParam); cpp_delete_context(ptr->cntx); ptr->cntx = 0; } ShowStatusIconNotify(wParam); return 1; }
void renameModule(char* oldName, char* newName, HANDLE hContact) { DBVARIANT dbv; ModuleSettingLL settinglist; ModSetLinkLinkItem *setting; if (!EnumSettings(hContact, oldName, &settinglist)) { msg(Translate("Error Loading Setting List"), modFullname); return; } setting = settinglist.first; while (setting) { if (!GetSetting(hContact, oldName, setting->name, &dbv)) { switch (dbv.type) { case DBVT_BYTE: db_set_b(hContact, newName, setting->name, dbv.bVal); break; case DBVT_WORD: db_set_w(hContact, newName, setting->name, dbv.wVal); break; case DBVT_DWORD: db_set_dw(hContact, newName, setting->name, dbv.dVal); break; case DBVT_ASCIIZ: db_set_s(hContact, newName, setting->name, dbv.pszVal); break; case DBVT_UTF8: db_set_utf(hContact, newName, setting->name, dbv.pszVal); break; case DBVT_BLOB: db_set_blob(hContact, newName, setting->name, dbv.pbVal, dbv.cpbVal); break; } db_unset(hContact, oldName, setting->name); } db_free(&dbv); setting = (ModSetLinkLinkItem *)setting->next; } FreeModuleSettingLL(&settinglist); }
void copyModule(char* module, MCONTACT hContactFrom, MCONTACT hContactTo) { ModuleSettingLL msll; EnumSettings(hContactFrom, module, &msll); ModSetLinkLinkItem *setting = msll.first; while (setting) { DBVARIANT dbv; if (!GetSetting(hContactFrom, module, setting->name, &dbv)) { switch (dbv.type) { case DBVT_BYTE: db_set_b(hContactTo, module, setting->name, dbv.bVal); break; case DBVT_WORD: db_set_w(hContactTo, module, setting->name, dbv.wVal); break; case DBVT_DWORD: db_set_dw(hContactTo, module, setting->name, dbv.dVal); break; case DBVT_ASCIIZ: db_set_s(hContactTo, module, setting->name, dbv.pszVal); break; case DBVT_UTF8: db_set_utf(hContactTo, module, setting->name, dbv.pszVal); break; case DBVT_BLOB: db_set_blob(hContactTo, module, setting->name, dbv.pbVal, dbv.cpbVal); break; } } db_free(&dbv); setting = setting->next; } FreeModuleSettingLL(&msll); }
inline static INT_PTR db_pod_set(HANDLE hContact,const char *module,const char *setting,T val) { return db_set_blob(hContact, module, setting, &val, sizeof(T)); }
INT_PTR CALLBACK DlgProcContainerOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TContainerData *pContainer = 0; HWND hwndTree = GetDlgItem(hwndDlg, IDC_SECTIONTREE); pContainer = (TContainerData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { wchar_t szNewTitle[128]; TContainerData *pContainer = 0; int i, j; TVINSERTSTRUCT tvis = {0}; HTREEITEM hItem; int nr_layouts = 0; const TSideBarLayout* sblayouts = CSideBar::getLayouts(nr_layouts); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) lParam); pContainer = (TContainerData *) lParam; pContainer->hWndOptions = hwndDlg; TranslateDialogDefault(hwndDlg); SetWindowText(hwndDlg, TranslateT("Container options")); mir_sntprintf(szNewTitle, SIZEOF(szNewTitle), TranslateT("Configure container options for\n%s"), !_tcscmp(pContainer->szName, _T("default")) ? TranslateT("Default container") : pContainer->szName); SetDlgItemText(hwndDlg, IDC_HEADERBAR, szNewTitle); Utils::enableDlgControl(hwndDlg, IDC_O_HIDETITLE, CSkin::m_frameSkins ? FALSE : TRUE); CheckDlgButton(hwndDlg, IDC_CNTPRIVATE, pContainer->settings->fPrivate ? BST_CHECKED : BST_UNCHECKED); SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Tabs at the top")); SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Tabs at the bottom")); SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Switch bar on the left side")); SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Switch bar on the right side")); SendDlgItemMessage(hwndDlg, IDC_AVATARMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Globally on")); SendDlgItemMessage(hwndDlg, IDC_AVATARMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("On, if present")); SendDlgItemMessage(hwndDlg, IDC_AVATARMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Globally OFF")); SendDlgItemMessage(hwndDlg, IDC_AVATARMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("On, if present, always in bottom display")); SendDlgItemMessage(hwndDlg, IDC_OWNAVATARMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("On, if present")); SendDlgItemMessage(hwndDlg, IDC_OWNAVATARMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Don't show them")); for (i=0; i < nr_layouts; i++) SendDlgItemMessage(hwndDlg, IDC_SBARLAYOUT, CB_INSERTSTRING, -1, (LPARAM)TranslateTS(sblayouts[i].szName)); /* bits 24 - 31 of dwFlagsEx hold the side bar layout id */ SendDlgItemMessage(hwndDlg, IDC_SBARLAYOUT, CB_SETCURSEL, (WPARAM)((pContainer->settings->dwFlagsEx & 0xff000000) >> 24), 0); SendMessage(hwndDlg, DM_SC_INITDIALOG, 0, (LPARAM)pContainer->settings); SendDlgItemMessage(hwndDlg, IDC_TITLEFORMAT, EM_LIMITTEXT, TITLE_FORMATLEN - 1, 0); SetDlgItemText(hwndDlg, IDC_TITLEFORMAT, pContainer->settings->szTitleFormat); SetDlgItemText(hwndDlg, IDC_THEME, pContainer->szRelThemeFile); for (i=0; i < NR_O_PAGES; i++) { tvis.hParent = NULL; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_TEXT | TVIF_PARAM; tvis.item.pszText = TranslateTS(o_pages[i].szTitle); tvis.item.lParam = i; hItem = TreeView_InsertItem(hwndTree, &tvis); if (i == 0) SendMessage(hwndTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); for (j = 0; j < NR_O_OPTIONSPERPAGE && o_pages[i].uIds[j] != 0; j++) Utils::showDlgControl(hwndDlg, o_pages[i].uIds[j], SW_HIDE); ShowPage(hwndDlg, i, FALSE); } SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIconBig(SKINICON_EVENT_MESSAGE)); ShowPage(hwndDlg, 0, TRUE); SetFocus(hwndTree); Utils::enableDlgControl(hwndDlg, IDC_APPLY, FALSE); HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_DESC, WM_GETFONT, 0, 0); LOGFONT lf = {0}; GetObject(hFont, sizeof(lf), &lf); lf.lfHeight = (int)(lf.lfHeight * 1.2); hFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_TITLEBOX, WM_SETFONT, (WPARAM)hFont, TRUE); if (pContainer->isCloned && pContainer->hContactFrom != 0) { Utils::showDlgControl(hwndDlg, IDC_CNTPRIVATE, SW_HIDE); Utils::showDlgControl(hwndDlg, IDC_O_CNTPRIVATE, SW_HIDE); } return FALSE; } case WM_CTLCOLOREDIT: case WM_CTLCOLORSTATIC: { HWND hwndChild = (HWND)lParam; UINT id = GetDlgCtrlID(hwndChild); if (hwndChild == GetDlgItem(hwndDlg, IDC_TITLEBOX)) { ::SetTextColor((HDC)wParam, RGB(60, 60, 150)); } else if (hwndChild == GetDlgItem(hwndDlg, IDC_DESC)) ::SetTextColor((HDC)wParam, RGB(160, 50, 50)); if (id == IDC_TSLABEL_REOPENWARN) break; SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); } case WM_NOTIFY: if (wParam == IDC_SECTIONTREE && ((LPNMHDR)lParam)->code == TVN_SELCHANGED) { NMTREEVIEW *pmtv = (NMTREEVIEW *)lParam; ShowPage(hwndDlg, pmtv->itemOld.lParam, 0); ShowPage(hwndDlg, pmtv->itemNew.lParam, 1); } break; case WM_HSCROLL: if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_TRANSPARENCY_ACTIVE) || (HWND)lParam == GetDlgItem(hwndDlg, IDC_TRANSPARENCY_INACTIVE)) Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_CNTPRIVATE: { if (IsDlgButtonChecked(hwndDlg, IDC_CNTPRIVATE)) { Utils::ReadPrivateContainerSettings(pContainer, true); pContainer->settings->fPrivate = true; } else { if (pContainer->settings != &PluginConfig.globalContainerSettings) { char szCname[40]; mir_snprintf(szCname, 40, "%s%d_Blob", CNT_BASEKEYNAME, pContainer->iContainerIndex); pContainer->settings->fPrivate = false; db_set_blob(0, SRMSGMOD_T, szCname, pContainer->settings, sizeof(TContainerSettings)); mir_free(pContainer->settings); } pContainer->settings = &PluginConfig.globalContainerSettings; pContainer->settings->fPrivate = false; } SendMessage(hwndDlg, DM_SC_INITDIALOG, 0, (LPARAM)pContainer->settings); goto do_apply; } case IDC_TRANSPARENCY: { int isTrans = IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENCY); Utils::enableDlgControl(hwndDlg, IDC_TRANSPARENCY_ACTIVE, isTrans ? TRUE : FALSE); Utils::enableDlgControl(hwndDlg, IDC_TRANSPARENCY_INACTIVE, isTrans ? TRUE : FALSE); goto do_apply; } case IDC_SECTIONTREE: case IDC_DESC: return 0; case IDC_SAVESIZEASGLOBAL: { WINDOWPLACEMENT wp = {0}; wp.length = sizeof(wp); if (GetWindowPlacement(pContainer->hwnd, &wp)) { db_set_dw(0, SRMSGMOD_T, "splitx", wp.rcNormalPosition.left); db_set_dw(0, SRMSGMOD_T, "splity", wp.rcNormalPosition.top); db_set_dw(0, SRMSGMOD_T, "splitwidth", wp.rcNormalPosition.right - wp.rcNormalPosition.left); db_set_dw(0, SRMSGMOD_T, "splitheight", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); } break; } case IDC_O_ENABLESOUNDS: SendMessage(hwndDlg, DM_SC_CONFIG, 0, 0); break; case IDC_TITLEFORMAT: if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()) return TRUE; goto do_apply; case IDC_SELECTTHEME: { const wchar_t *szFileName = GetThemeFileName(0); if (PathFileExists(szFileName)) { SetDlgItemText(hwndDlg, IDC_THEME, szFileName); goto do_apply; } break; } case IDC_O_HELP_TITLEFORMAT: CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW|OUF_TCHAR, (LPARAM)_T("http://miranda.or.at/TabSRMM/TitleBarFormatting")); break; case IDOK: case IDC_APPLY: { SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, (LPARAM)pContainer->settings); pContainer->settings->dwTransparency = MAKELONG((WORD)SendDlgItemMessage(hwndDlg, IDC_TRANSPARENCY_ACTIVE, TBM_GETPOS, 0, 0), (WORD)SendDlgItemMessage(hwndDlg, IDC_TRANSPARENCY_INACTIVE, TBM_GETPOS, 0, 0)); pContainer->settings->avatarMode = (WORD)SendDlgItemMessage(hwndDlg, IDC_AVATARMODE, CB_GETCURSEL, 0, 0); pContainer->settings->ownAvatarMode = (WORD)SendDlgItemMessage(hwndDlg, IDC_OWNAVATARMODE, CB_GETCURSEL, 0, 0); GetDlgItemText(hwndDlg, IDC_TITLEFORMAT, pContainer->settings->szTitleFormat, TITLE_FORMATLEN); pContainer->settings->szTitleFormat[TITLE_FORMATLEN - 1] = 0; pContainer->szRelThemeFile[0] = pContainer->szAbsThemeFile[0] = 0; if (GetWindowTextLengthA(GetDlgItem(hwndDlg, IDC_THEME)) > 0) { wchar_t szFinalThemeFile[MAX_PATH], szFilename[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_THEME, szFilename, MAX_PATH); szFilename[MAX_PATH - 1] = 0; M.pathToAbsolute(szFilename, szFinalThemeFile); if (_tcscmp(szFilename, pContainer->szRelThemeFile)) pContainer->fPrivateThemeChanged = TRUE; if (PathFileExists(szFinalThemeFile)) mir_sntprintf(pContainer->szRelThemeFile, MAX_PATH, _T("%s"), szFilename); else pContainer->szRelThemeFile[0] = 0; } else { pContainer->szRelThemeFile[0] = 0; pContainer->fPrivateThemeChanged = TRUE; } Utils::SettingsToContainer(pContainer); if (!IsDlgButtonChecked(hwndDlg, IDC_CNTPRIVATE)) { ReloadGlobalContainerSettings(true); ::db_set_blob(0, SRMSGMOD_T, CNT_KEYNAME, &PluginConfig.globalContainerSettings, sizeof(TContainerSettings)); } else { char *szSetting = "CNTW_"; Utils::SaveContainerSettings(pContainer, szSetting); } SendMessage(pContainer->hwnd, DM_CONFIGURECONTAINER, 0, 0); BroadCastContainer(pContainer, DM_SETINFOPANEL, 0, 0); ShowWindow(pContainer->hwnd, SW_HIDE); { RECT rc; GetWindowRect(pContainer->hwnd, &rc); SetWindowPos(pContainer->hwnd, 0, rc.left, rc.top, (rc.right - rc.left) - 1, (rc.bottom - rc.top) - 1, SWP_NOZORDER | SWP_DRAWFRAME | SWP_FRAMECHANGED); SetWindowPos(pContainer->hwnd, 0, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), SWP_NOZORDER | SWP_DRAWFRAME | SWP_SHOWWINDOW); } if (LOWORD(wParam) == IDOK) DestroyWindow(hwndDlg); else Utils::enableDlgControl(hwndDlg, IDC_APPLY, FALSE); break; } case IDCANCEL: DestroyWindow(hwndDlg); return TRUE; default: do_apply: Utils::enableDlgControl(hwndDlg, IDC_APPLY, TRUE); break; } break; case DM_SC_INITDIALOG: { TContainerSettings* cs = (TContainerSettings *)lParam; DWORD dwFlags = cs->dwFlags; DWORD dwTransparency = cs->dwTransparency; DWORD dwFlagsEx = cs->dwFlagsEx; int isTrans; BOOL fAllowTrans = FALSE; if (PluginConfig.m_WinVerMajor >= 6) fAllowTrans = TRUE; else fAllowTrans = (!CSkin::m_skinEnabled); MY_CheckDlgButton(hwndDlg, IDC_O_HIDETITLE, dwFlags & CNT_NOTITLE); MY_CheckDlgButton(hwndDlg, IDC_O_DONTREPORT, dwFlags & CNT_DONTREPORT); MY_CheckDlgButton(hwndDlg, IDC_O_NOTABS, dwFlags & CNT_HIDETABS); MY_CheckDlgButton(hwndDlg, IDC_O_STICKY, dwFlags & CNT_STICKY); MY_CheckDlgButton(hwndDlg, IDC_O_FLASHNEVER, dwFlags & CNT_NOFLASH); MY_CheckDlgButton(hwndDlg, IDC_O_FLASHALWAYS, dwFlags & CNT_FLASHALWAYS); MY_CheckDlgButton(hwndDlg, IDC_O_FLASHDEFAULT, !((dwFlags & CNT_NOFLASH) || (dwFlags & CNT_FLASHALWAYS))); MY_CheckDlgButton(hwndDlg, IDC_TRANSPARENCY, dwFlags & CNT_TRANSPARENCY); MY_CheckDlgButton(hwndDlg, IDC_DONTREPORTUNFOCUSED2, dwFlags & CNT_DONTREPORTUNFOCUSED); MY_CheckDlgButton(hwndDlg, IDC_DONTREPORTFOCUSED2, dwFlags & CNT_DONTREPORTFOCUSED); MY_CheckDlgButton(hwndDlg, IDC_ALWAYSPOPUPSINACTIVE, dwFlags & CNT_ALWAYSREPORTINACTIVE); MY_CheckDlgButton(hwndDlg, IDC_CNTNOSTATUSBAR, dwFlags & CNT_NOSTATUSBAR); MY_CheckDlgButton(hwndDlg, IDC_HIDEMENUBAR, dwFlags & CNT_NOMENUBAR); MY_CheckDlgButton(hwndDlg, IDC_HIDETOOLBAR, dwFlags & CNT_HIDETOOLBAR); MY_CheckDlgButton(hwndDlg, IDC_BOTTOMTOOLBAR, dwFlags & CNT_BOTTOMTOOLBAR); MY_CheckDlgButton(hwndDlg, IDC_UIDSTATUSBAR, dwFlags & CNT_UINSTATUSBAR); MY_CheckDlgButton(hwndDlg, IDC_VERTICALMAX, dwFlags & CNT_VERTICALMAX); #if defined(__FEAT_EXP_AUTOSPLITTER) MY_CheckDlgButton(hwndDlg, IDC_AUTOSPLITTER, dwFlags & CNT_AUTOSPLITTER); #endif MY_CheckDlgButton(hwndDlg, IDC_AVATARSONTASKBAR, dwFlags & CNT_AVATARSONTASKBAR); MY_CheckDlgButton(hwndDlg, IDC_INFOPANEL, dwFlags & CNT_INFOPANEL); MY_CheckDlgButton(hwndDlg, IDC_USEGLOBALSIZE, dwFlags & CNT_GLOBALSIZE); MY_CheckDlgButton(hwndDlg, IDC_FLASHICON, dwFlagsEx & TCF_FLASHICON); MY_CheckDlgButton(hwndDlg, IDC_FLASHLABEL, dwFlagsEx & TCF_FLASHLABEL); MY_CheckDlgButton(hwndDlg, IDC_CLOSEBUTTONONTABS, dwFlagsEx & TCF_CLOSEBUTTON); MY_CheckDlgButton(hwndDlg, IDC_SINGLEROWTAB, dwFlagsEx & TCF_SINGLEROWTABCONTROL); MY_CheckDlgButton(hwndDlg, IDC_BUTTONTABS, dwFlagsEx & TCF_FLAT); MY_CheckDlgButton(hwndDlg, IDC_O_ENABLESOUNDS, !(dwFlags & CNT_NOSOUND)); MY_CheckDlgButton(hwndDlg, IDC_O_SOUNDSMINIMIZED, dwFlagsEx & CNT_EX_SOUNDS_MINIMIZED); MY_CheckDlgButton(hwndDlg, IDC_O_SOUNDSUNFOCUSED, dwFlagsEx & CNT_EX_SOUNDS_UNFOCUSED); MY_CheckDlgButton(hwndDlg, IDC_O_SOUNDSINACTIVE, dwFlagsEx & CNT_EX_SOUNDS_INACTIVETABS); MY_CheckDlgButton(hwndDlg, IDC_O_SOUNDSFOCUSED, dwFlagsEx & CNT_EX_SOUNDS_FOCUSED); SendMessage(hwndDlg, DM_SC_CONFIG, 0, 0); if (!(dwFlagsEx & (TCF_SBARLEFT | TCF_SBARRIGHT))) SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_SETCURSEL, dwFlags & CNT_TABSBOTTOM ? 1 : 0, 0); else SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_SETCURSEL, dwFlagsEx & TCF_SBARLEFT ? 2 : 3, 0); if (LOBYTE(LOWORD(GetVersion())) >= 5 && fAllowTrans) CheckDlgButton(hwndDlg, IDC_TRANSPARENCY, dwFlags & CNT_TRANSPARENCY); else CheckDlgButton(hwndDlg, IDC_TRANSPARENCY, FALSE); Utils::enableDlgControl(hwndDlg, IDC_TRANSPARENCY, PluginConfig.m_WinVerMajor >= 5 && fAllowTrans ? TRUE : FALSE); isTrans = IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENCY); Utils::enableDlgControl(hwndDlg, IDC_TRANSPARENCY_ACTIVE, isTrans ? TRUE : FALSE); Utils::enableDlgControl(hwndDlg, IDC_TRANSPARENCY_INACTIVE, isTrans ? TRUE : FALSE); SendDlgItemMessage(hwndDlg, IDC_TRANSPARENCY_ACTIVE, TBM_SETRANGE, 0, (LPARAM)MAKELONG(50, 255)); SendDlgItemMessage(hwndDlg, IDC_TRANSPARENCY_INACTIVE, TBM_SETRANGE, 0, (LPARAM)MAKELONG(50, 255)); SendDlgItemMessage(hwndDlg, IDC_TRANSPARENCY_ACTIVE, TBM_SETPOS, TRUE, (LPARAM)LOWORD(dwTransparency)); SendDlgItemMessage(hwndDlg, IDC_TRANSPARENCY_INACTIVE, TBM_SETPOS, TRUE, (LPARAM)HIWORD(dwTransparency)); Utils::enableDlgControl(hwndDlg, IDC_O_DONTREPORT, nen_options.bWindowCheck == 0); Utils::enableDlgControl(hwndDlg, IDC_DONTREPORTUNFOCUSED2, nen_options.bWindowCheck == 0); Utils::enableDlgControl(hwndDlg, IDC_DONTREPORTFOCUSED2, nen_options.bWindowCheck == 0); Utils::enableDlgControl(hwndDlg, IDC_ALWAYSPOPUPSINACTIVE, nen_options.bWindowCheck == 0); SendDlgItemMessage(hwndDlg, IDC_AVATARMODE, CB_SETCURSEL, (WPARAM)cs->avatarMode, 0); SendDlgItemMessage(hwndDlg, IDC_OWNAVATARMODE, CB_SETCURSEL, (WPARAM)cs->ownAvatarMode, 0); Utils::showDlgControl(hwndDlg, IDC_O_EXPLAINGLOBALNOTIFY, nen_options.bWindowCheck ? SW_SHOW : SW_HIDE); SendDlgItemMessage(hwndDlg, IDC_AUTOCLOSETABSPIN, UDM_SETRANGE, 0, MAKELONG(1000, 0)); SendDlgItemMessage(hwndDlg, IDC_AUTOCLOSETABSPIN, UDM_SETPOS, 0, (LPARAM)cs->autoCloseSeconds); break; } case DM_SC_CONFIG: { LRESULT enable = (IsDlgButtonChecked(hwndDlg, IDC_O_ENABLESOUNDS) ? BST_CHECKED : BST_UNCHECKED); Utils::enableDlgControl(hwndDlg, IDC_O_SOUNDSINACTIVE, enable); Utils::enableDlgControl(hwndDlg, IDC_O_SOUNDSUNFOCUSED, enable); Utils::enableDlgControl(hwndDlg, IDC_O_SOUNDSMINIMIZED, enable); Utils::enableDlgControl(hwndDlg, IDC_O_SOUNDSFOCUSED, enable); return 0; } case DM_SC_BUILDLIST: { DWORD dwNewFlags = 0, dwNewFlagsEx = 0; TContainerSettings* cs = (TContainerSettings *)lParam; dwNewFlags = (IsDlgButtonChecked(hwndDlg, IDC_O_HIDETITLE) ? CNT_NOTITLE : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_DONTREPORT) ? CNT_DONTREPORT : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_NOTABS) ? CNT_HIDETABS : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_STICKY) ? CNT_STICKY : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_FLASHALWAYS) ? CNT_FLASHALWAYS : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_FLASHNEVER) ? CNT_NOFLASH : 0) | (IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENCY) ? CNT_TRANSPARENCY : 0) | (IsDlgButtonChecked(hwndDlg, IDC_DONTREPORTUNFOCUSED2) ? CNT_DONTREPORTUNFOCUSED : 0) | (IsDlgButtonChecked(hwndDlg, IDC_DONTREPORTFOCUSED2) ? CNT_DONTREPORTFOCUSED : 0) | (IsDlgButtonChecked(hwndDlg, IDC_ALWAYSPOPUPSINACTIVE) ? CNT_ALWAYSREPORTINACTIVE : 0) | (IsDlgButtonChecked(hwndDlg, IDC_CNTNOSTATUSBAR) ? CNT_NOSTATUSBAR : 0) | (IsDlgButtonChecked(hwndDlg, IDC_HIDEMENUBAR) ? CNT_NOMENUBAR : 0) | (IsDlgButtonChecked(hwndDlg, IDC_HIDETOOLBAR) ? CNT_HIDETOOLBAR : 0) | (IsDlgButtonChecked(hwndDlg, IDC_BOTTOMTOOLBAR) ? CNT_BOTTOMTOOLBAR : 0) | (IsDlgButtonChecked(hwndDlg, IDC_UIDSTATUSBAR) ? CNT_UINSTATUSBAR : 0) | (IsDlgButtonChecked(hwndDlg, IDC_USEGLOBALSIZE) ? CNT_GLOBALSIZE : 0) | (IsDlgButtonChecked(hwndDlg, IDC_INFOPANEL) ? CNT_INFOPANEL : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_ENABLESOUNDS) ? 0 : CNT_NOSOUND) | (IsDlgButtonChecked(hwndDlg, IDC_AVATARSONTASKBAR) ? CNT_AVATARSONTASKBAR : 0) | (IsDlgButtonChecked(hwndDlg, IDC_VERTICALMAX) ? CNT_VERTICALMAX : 0) | #if defined(__FEAT_EXP_AUTOSPLITTER) (IsDlgButtonChecked(hwndDlg, IDC_AUTOSPLITTER) ? CNT_AUTOSPLITTER : 0) | #endif (CNT_NEWCONTAINERFLAGS); LRESULT iTabMode = SendDlgItemMessage(hwndDlg, IDC_TABMODE, CB_GETCURSEL, 0, 0); LRESULT iTabLayout = SendDlgItemMessage(hwndDlg, IDC_SBARLAYOUT, CB_GETCURSEL, 0, 0); dwNewFlagsEx = 0; if (iTabMode < 2) dwNewFlags = ((iTabMode == 1) ? (dwNewFlags | CNT_TABSBOTTOM) : (dwNewFlags & ~CNT_TABSBOTTOM)); else { dwNewFlags &= ~CNT_TABSBOTTOM; dwNewFlagsEx = iTabMode == 2 ? TCF_SBARLEFT : TCF_SBARRIGHT; } dwNewFlagsEx |= ((IsDlgButtonChecked(hwndDlg, IDC_FLASHICON) ? TCF_FLASHICON : 0) | (IsDlgButtonChecked(hwndDlg, IDC_FLASHLABEL) ? TCF_FLASHLABEL : 0) | (IsDlgButtonChecked(hwndDlg, IDC_BUTTONTABS) ? TCF_FLAT : 0) | (IsDlgButtonChecked(hwndDlg, IDC_CLOSEBUTTONONTABS) ? TCF_CLOSEBUTTON : 0) | (IsDlgButtonChecked(hwndDlg, IDC_SINGLEROWTAB) ? TCF_SINGLEROWTABCONTROL : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_SOUNDSMINIMIZED) ? CNT_EX_SOUNDS_MINIMIZED : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_SOUNDSUNFOCUSED) ? CNT_EX_SOUNDS_UNFOCUSED : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_SOUNDSFOCUSED) ? CNT_EX_SOUNDS_FOCUSED : 0) | (IsDlgButtonChecked(hwndDlg, IDC_O_SOUNDSINACTIVE) ? CNT_EX_SOUNDS_INACTIVETABS : 0) ); /* bits 24 - 31 of dwFlagsEx hold the sidebar layout id */ dwNewFlagsEx |= ((int)((iTabLayout << 24) & 0xff000000)); if (IsDlgButtonChecked(hwndDlg, IDC_O_FLASHDEFAULT)) dwNewFlags &= ~(CNT_FLASHALWAYS | CNT_NOFLASH); cs->dwFlags = dwNewFlags; cs->dwFlagsEx = dwNewFlagsEx; cs->autoCloseSeconds = (WORD)SendDlgItemMessage(hwndDlg, IDC_AUTOCLOSETABSPIN, UDM_GETPOS, 0, 0); break; } case WM_DESTROY: { pContainer->hWndOptions = 0; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_TITLEBOX, WM_GETFONT, 0, 0); DeleteObject(hFont); break; } } return FALSE; }
bool CToxProto::SetToxAvatar(std::tstring path, bool checkHash) { int length; uint8_t *data; FILE *hFile = _tfopen(path.c_str(), L"rb"); if (!hFile) { debugLogA("CToxProto::SetMyAvatar: failed to open avatar file"); return false; } fseek(hFile, 0, SEEK_END); length = ftell(hFile); rewind(hFile); if (length > TOX_AVATAR_MAX_DATA_LENGTH) { fclose(hFile); debugLogA("CToxProto::SetMyAvatar: new avatar size is excessive"); return false; } data = (uint8_t*)mir_alloc(length); size_t readed = fread(data, sizeof(uint8_t), length, hFile); if (readed != length) { fclose(hFile); debugLogA("CToxProto::SetMyAvatar: failed to read avatar file"); return false; } fclose(hFile); DBVARIANT dbv; uint8_t hash[TOX_HASH_LENGTH]; tox_hash(hash, data, TOX_HASH_LENGTH); if (checkHash && !db_get(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, &dbv)) { if (memcmp(hash, dbv.pbVal, TOX_HASH_LENGTH) == 0) { db_free(&dbv); mir_free(data); debugLogA("CToxProto::SetMyAvatar: new avatar is same with old"); return false; } db_free(&dbv); } if (tox_set_avatar(tox, TOX_AVATAR_FORMAT_PNG, data, length) == TOX_ERROR) { mir_free(data); debugLogA("CToxProto::SetMyAvatar: failed to set new avatar"); return false; } mir_free(data); if (checkHash) { db_set_blob(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, (void*)hash, TOX_HASH_LENGTH); } return true; }
void WriteLastCheckTime() { // save last-check time db_set_blob(NULL, MODULE, "LastCheck", &last_check, sizeof(SYSTEMTIME)); last_saved_check = last_check; }
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; }
int replaceModule(HWND hwnd, HANDLE hContact, const char *module, const char *find, const char *replace, int mode) { ModuleSettingLL msll; ModSetLinkLinkItem *setting; char *myreplace = NULL; char *newModule; int count = 0; if (mode & RW_FULL) newModule = (char*)replace; else { myreplace = multiReplace(module, find, replace, mode & RW_CASE); newModule = myreplace; } if (newModule[0] == 0) { ItemFound(hwnd, hContact, module, NULL, NULL, FW_MODULE | FW_DELETED); deleteModule((char*)module, hContact, 1); replaceTreeItem(GetDlgItem(hwnd2mainWindow, IDC_MODULES), hContact, module, NULL); mir_free(myreplace); return 1; } if (!IsModuleEmpty(hContact, newModule)) return 0; if (EnumSettings(hContact, (char*)module, &msll)) { setting = msll.first; while (setting) { DBVARIANT dbv; if (!GetSetting(hContact, module, setting->name, &dbv)) { switch (dbv.type) { case DBVT_BYTE: db_set_b(hContact, newModule, setting->name, dbv.bVal); break; case DBVT_WORD: db_set_w(hContact, newModule, setting->name, dbv.wVal); break; case DBVT_DWORD: db_set_dw(hContact, newModule, setting->name, dbv.dVal); break; case DBVT_ASCIIZ: db_set_s(hContact, newModule, setting->name, dbv.pszVal); break; case DBVT_UTF8: db_set_utf(hContact, newModule, setting->name, dbv.pszVal); break; case DBVT_BLOB: db_set_blob(hContact, newModule, setting->name, dbv.pbVal, dbv.cpbVal); break; } db_free(&dbv); db_unset(hContact, module, setting->name); } setting = setting->next; } FreeModuleSettingLL(&msll); replaceTreeItem(GetDlgItem(hwnd2mainWindow, IDC_MODULES), hContact, module, newModule); ItemFound(hwnd, hContact, newModule, NULL, NULL, FW_MODULE | FW_REPLACED); count++; } mir_free(myreplace); return count; }
bool Quotes_DBWriteDouble(MCONTACT hContact, const char* szModule, const char* szSetting, double dValue) { return 0 == db_set_blob(hContact, szModule, szSetting, &dValue, sizeof(dValue)); }
void CToxProto::SetToxAvatar(std::tstring path) { FILE *hFile = _tfopen(path.c_str(), L"rb"); if (!hFile) { debugLogA(__FUNCTION__": failed to open avatar file"); return; } fseek(hFile, 0, SEEK_END); size_t length = ftell(hFile); rewind(hFile); if (length > TOX_MAX_AVATAR_SIZE) { fclose(hFile); debugLogA(__FUNCTION__": new avatar size is excessive"); return; } uint8_t *data = (uint8_t*)mir_alloc(length); if (fread(data, sizeof(uint8_t), length, hFile) != length) { fclose(hFile); debugLogA(__FUNCTION__": failed to read avatar file"); mir_free(data); return; } fclose(hFile); DBVARIANT dbv; uint8_t hash[TOX_HASH_LENGTH]; tox_hash(hash, data, TOX_HASH_LENGTH); if (!db_get(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, &dbv)) { if (memcmp(hash, dbv.pbVal, TOX_HASH_LENGTH) == 0) { db_free(&dbv); mir_free(data); debugLogA(__FUNCTION__": new avatar is same with old"); return; } db_free(&dbv); } db_set_blob(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, (void*)hash, TOX_HASH_LENGTH); if (IsOnline()) { for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { if (GetContactStatus(hContact) == ID_STATUS_OFFLINE) continue; int32_t friendNumber = GetToxFriendNumber(hContact); if (friendNumber == UINT32_MAX) { mir_free(data); debugLogA(__FUNCTION__": failed to set new avatar"); return; } TOX_ERR_FILE_SEND error; uint32_t fileNumber = tox_file_send(tox, friendNumber, TOX_FILE_KIND_AVATAR, length, hash, NULL, 0, &error); if (error != TOX_ERR_FILE_SEND_OK) { mir_free(data); debugLogA(__FUNCTION__": failed to set new avatar"); return; } AvatarTransferParam *transfer = new AvatarTransferParam(friendNumber, fileNumber, NULL, length); transfer->pfts.flags |= PFTS_SENDING; memcpy(transfer->hash, hash, TOX_HASH_LENGTH); transfer->pfts.hContact = hContact; transfer->hFile = _tfopen(path.c_str(), L"rb"); transfers.Add(transfer); } } mir_free(data); }
static void ProcessIniFile(TCHAR* szIniPath, char *szSafeSections, char *szUnsafeSections, int secur, bool secFN) { FILE *fp = _tfopen(szIniPath, _T("rt")); if (fp == NULL) return; bool warnThisSection = false; char szSection[128]; szSection[0] = 0; while (!feof(fp)) { char szLine[2048]; if (fgets(szLine, sizeof(szLine), fp) == NULL) break; LBL_NewLine: size_t lineLength = mir_strlen(szLine); while (lineLength && (BYTE)(szLine[lineLength - 1]) <= ' ') szLine[--lineLength] = '\0'; if (szLine[0] == ';' || szLine[0] <= ' ') continue; if (szLine[0] == '[') { char *szEnd = strchr(szLine + 1, ']'); if (szEnd == NULL) continue; if (szLine[1] == '!') szSection[0] = '\0'; else { mir_strncpy(szSection, szLine + 1, min(sizeof(szSection), (int)(szEnd - szLine))); switch (secur) { case 0: warnThisSection = false; break; case 1: warnThisSection = !IsInSpaceSeparatedList(szSection, szSafeSections); break; case 2: warnThisSection = IsInSpaceSeparatedList(szSection, szUnsafeSections); break; default: warnThisSection = true; break; } if (secFN) warnThisSection = 0; } if (szLine[1] == '?') { DBCONTACTENUMSETTINGS dbces; dbces.pfnEnumProc = SettingsEnumProc; mir_strncpy(szSection, szLine+2, min(sizeof(szSection), (int)(szEnd-szLine-1))); dbces.szModule = szSection; dbces.ofsSettings = 0; CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&dbces); while (setting_items) { SettingsList *next = setting_items->next; db_unset(NULL, szSection, setting_items->name); mir_free(setting_items->name); mir_free(setting_items); setting_items = next; } } continue; } if (szSection[0] == '\0') continue; char *szValue = strchr(szLine, '='); if (szValue == NULL) continue; char szName[128]; mir_strncpy(szName, szLine, min(sizeof(szName), (int)(szValue-szLine+1))); szValue++; { warnSettingChangeInfo_t warnInfo; warnInfo.szIniPath = szIniPath; warnInfo.szName = szName; warnInfo.szSafeSections = szSafeSections; warnInfo.szSection = szSection; warnInfo.szUnsafeSections = szUnsafeSections; warnInfo.szValue = szValue; warnInfo.warnNoMore = 0; warnInfo.cancel = 0; if (warnThisSection && IDNO == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_WARNINICHANGE), NULL, WarnIniChangeDlgProc, (LPARAM)&warnInfo)) continue; if (warnInfo.cancel) break; if (warnInfo.warnNoMore) warnThisSection = 0; } switch (szValue[0]) { case 'b': case 'B': db_set_b(NULL, szSection, szName, (BYTE)strtol(szValue+1, NULL, 0)); break; case 'w': case 'W': db_set_w(NULL, szSection, szName, (WORD)strtol(szValue+1, NULL, 0)); break; case 'd': case 'D': db_set_dw(NULL, szSection, szName, (DWORD)strtoul(szValue+1, NULL, 0)); break; case 'l': case 'L': case '-': if (szValue[1] == '*') { LIST<char> arSettings(1); ESFDParam param = { &arSettings, szName }; DBCONTACTENUMSETTINGS dbep = {}; dbep.pfnEnumProc = EnumSettingsForDeletion; dbep.szModule = szSection; dbep.lParam = (LPARAM)¶m; CallService(MS_DB_CONTACT_ENUMSETTINGS, NULL, LPARAM(&dbep)); while (arSettings.getCount()) { db_unset(NULL, szSection, arSettings[0]); mir_free(arSettings[0]); arSettings.remove(0); } } db_unset(NULL, szSection, szName); break; case 'e': case 'E': ConvertBackslashes(szValue+1, Langpack_GetDefaultCodePage()); case 's': case 'S': db_set_s(NULL, szSection, szName, szValue+1); break; case 'g': case 'G': for (char *pstr = szValue + 1; *pstr; pstr++) { if (*pstr == '\\') { switch (pstr[1]) { case 'n': *pstr = '\n'; break; case 't': *pstr = '\t'; break; case 'r': *pstr = '\r'; break; default: *pstr = pstr[1]; break; } memmove(pstr + 1, pstr + 2, mir_strlen(pstr + 2) + 1); } } case 'u': case 'U': db_set_utf(NULL, szSection, szName, szValue + 1); break; case 'm': case 'M': { CMStringA memo(szValue + 1); memo.Append("\r\n"); while (fgets(szLine, sizeof(szLine), fp) != NULL) { switch (szLine[0]) { case 0: case '\r': case '\n': case ' ': case '\t': break; default: db_set_utf(NULL, szSection, szName, memo); goto LBL_NewLine; } memo.Append(rtrim(szLine + 1)); memo.Append("\r\n"); } db_set_utf(NULL, szSection, szName, memo); } break; case 'n': case 'h': case 'N': case 'H': { int len; char *pszValue, *pszEnd; PBYTE buf = (PBYTE)mir_alloc(mir_strlen(szValue + 1)); for (len = 0, pszValue = szValue + 1;; len++) { buf[len] = (BYTE)strtol(pszValue, &pszEnd, 0x10); if (pszValue == pszEnd) break; pszValue = pszEnd; } db_set_blob(NULL, szSection, szName, buf, len); mir_free(buf); } break; default: TCHAR buf[250]; mir_sntprintf(buf, TranslateT("Invalid setting type for '%s'. The first character of every value must be b, w, d, l, s, e, u, g, h or n."), _A2T(szName)); MessageBox(NULL, buf, TranslateT("Install database settings"), MB_ICONWARNING | MB_OK); break; } } fclose(fp); }
static INT_PTR CALLBACK ContactOpts(HWND hwndDlg, UINT msg, WPARAM, LPARAM lParam) { struct ContactOptionsData *dat = (struct ContactOptionsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); dat = (struct ContactOptionsData*)mir_alloc(sizeof(struct ContactOptionsData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->dragging = 0; SetWindowLongPtr( GetDlgItem(hwndDlg, IDC_NAMEORDER), GWL_STYLE, GetWindowLongPtr( GetDlgItem(hwndDlg, IDC_NAMEORDER), GWL_STYLE)|TVS_NOHSCROLL); { TVINSERTSTRUCT tvis; tvis.hParent = NULL; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_TEXT|TVIF_PARAM; for (int i=0; i < SIZEOF(nameOrderDescr); i++) { tvis.item.lParam = nameOrder[i]; tvis.item.pszText = TranslateTS(nameOrderDescr[ nameOrder[i]]); TreeView_InsertItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), &tvis); } } return TRUE; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: if (((LPNMHDR)lParam)->code == PSN_APPLY) { TVITEM tvi; tvi.hItem = TreeView_GetRoot( GetDlgItem(hwndDlg, IDC_NAMEORDER)); int i=0; while (tvi.hItem != NULL) { tvi.mask = TVIF_PARAM | TVIF_HANDLE; TreeView_GetItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), &tvi); nameOrder[i++] = (BYTE)tvi.lParam; tvi.hItem = TreeView_GetNextSibling( GetDlgItem(hwndDlg, IDC_NAMEORDER), tvi.hItem); } db_set_blob(NULL, "Contact", "NameOrder", nameOrder, SIZEOF(nameOrderDescr)); CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)INVALID_HANDLE_VALUE, 0); } break; case IDC_NAMEORDER: if (((LPNMHDR)lParam)->code == TVN_BEGINDRAGA) { LPNMTREEVIEWA notify = (LPNMTREEVIEWA)lParam; if (notify->itemNew.lParam == 0 || notify->itemNew.lParam == SIZEOF(nameOrderDescr)-1) break; SetCapture(hwndDlg); dat->dragging = 1; dat->hDragItem = ((LPNMTREEVIEW)lParam)->itemNew.hItem; TreeView_SelectItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), dat->hDragItem); } } break; case WM_MOUSEMOVE: if (dat->dragging) { TVHITTESTINFO hti; hti.pt.x = (short)LOWORD(lParam); hti.pt.y = (short)HIWORD(lParam); ClientToScreen(hwndDlg, &hti.pt); ScreenToClient( GetDlgItem(hwndDlg, IDC_NAMEORDER), &hti.pt); TreeView_HitTest( GetDlgItem(hwndDlg, IDC_NAMEORDER), &hti); if (hti.flags&(TVHT_ONITEM|TVHT_ONITEMRIGHT)) { hti.pt.y-=TreeView_GetItemHeight( GetDlgItem(hwndDlg, IDC_NAMEORDER))/2; TreeView_HitTest( GetDlgItem(hwndDlg, IDC_NAMEORDER), &hti); TreeView_SetInsertMark( GetDlgItem(hwndDlg, IDC_NAMEORDER), hti.hItem, 1); } else { if (hti.flags&TVHT_ABOVE) SendDlgItemMessage(hwndDlg, IDC_NAMEORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); if (hti.flags&TVHT_BELOW) SendDlgItemMessage(hwndDlg, IDC_NAMEORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); TreeView_SetInsertMark( GetDlgItem(hwndDlg, IDC_NAMEORDER), NULL, 0); } } break; case WM_LBUTTONUP: if (dat->dragging) { TreeView_SetInsertMark( GetDlgItem(hwndDlg, IDC_NAMEORDER), NULL, 0); dat->dragging = 0; ReleaseCapture(); TVHITTESTINFO hti; TVITEM tvi; hti.pt.x = (short)LOWORD(lParam); hti.pt.y = (short)HIWORD(lParam); ClientToScreen(hwndDlg, &hti.pt); ScreenToClient( GetDlgItem(hwndDlg, IDC_NAMEORDER), &hti.pt); hti.pt.y-=TreeView_GetItemHeight( GetDlgItem(hwndDlg, IDC_NAMEORDER))/2; TreeView_HitTest( GetDlgItem(hwndDlg, IDC_NAMEORDER), &hti); if (dat->hDragItem == hti.hItem) break; tvi.mask = TVIF_HANDLE|TVIF_PARAM; tvi.hItem = hti.hItem; TreeView_GetItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), &tvi); if (tvi.lParam == SIZEOF(nameOrderDescr)-1) break; if (hti.flags&(TVHT_ONITEM|TVHT_ONITEMRIGHT)) { TVINSERTSTRUCT tvis; TCHAR name[128]; tvis.item.mask = TVIF_HANDLE|TVIF_PARAM|TVIF_TEXT|TVIF_PARAM; tvis.item.stateMask = 0xFFFFFFFF; tvis.item.pszText = name; tvis.item.cchTextMax = SIZEOF(name); tvis.item.hItem = dat->hDragItem; TreeView_GetItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), &tvis.item); TreeView_DeleteItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), dat->hDragItem); tvis.hParent = NULL; tvis.hInsertAfter = hti.hItem; TreeView_SelectItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), TreeView_InsertItem( GetDlgItem(hwndDlg, IDC_NAMEORDER), &tvis)); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } } break; case WM_DESTROY: mir_free(dat); break; } return FALSE; }