HANDLE CYahooProto::AddToList( int flags, PROTOSEARCHRESULT* psr ) { debugLogA("[YahooAddToList] Flags: %d", flags); if (!m_bLoggedIn) { debugLogA("[YahooAddToList] WARNING: WE ARE OFFLINE!"); return 0; } if (psr == NULL || psr->cbSize != sizeof( PROTOSEARCHRESULT )) { debugLogA("[YahooAddToList] Empty data passed?"); return 0; } char *id = psr->flags & PSR_UNICODE ? mir_utf8encodeW((wchar_t*)psr->id) : mir_utf8encode((char*)psr->id); HANDLE hContact = getbuddyH(id); if (hContact != NULL) { if (db_get_b(hContact, "CList", "NotOnList", 0)) { debugLogA("[YahooAddToList] Temporary Buddy:%s already on our buddy list", id); //return 0; } else { debugLogA("[YahooAddToList] Buddy:%s already on our buddy list", id); mir_free(id); return 0; } } else if (flags & PALF_TEMPORARY) { /* not on our list */ debugLogA("[YahooAddToList] Adding Temporary Buddy:%s ", id); } int protocol = psr->reserved[0]; debugLogA("Adding buddy:%s", id); hContact = add_buddy(id, id, protocol, flags); mir_free(id); return hContact; }
tstring GetContactUid(HANDLE hContact, tstring Protocol) { tstring Uid; TCHAR dUid[32]={0}; char aUid[32]={0}; char *szProto = mir_utf8encodeW(Protocol.c_str()); CONTACTINFO ci; ZeroMemory((void *)&ci, sizeof(ci)); ci.hContact = hContact; ci.szProto = szProto; ci.cbSize = sizeof(ci); ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { switch (ci.type) { case CNFT_ASCIIZ: Uid=ci.pszVal; mir_free((void *)ci.pszVal); break; case CNFT_DWORD: _itoa_s(ci.dVal,aUid,32,10); OemToChar(aUid, dUid); Uid=dUid; break; default: Uid=_T(""); break; }; } mir_free(szProto); return Uid; }
int __cdecl CYahooProto::SendMsg( HANDLE hContact, int flags, const char* pszSrc ) { if (!m_bLoggedIn) {/* don't send message if we not connected! */ ForkThread( &CYahooProto::im_sendackfail, hContact ); return 1; } ptrA msg; if (flags & PREF_UNICODE) /* convert to utf8 */ msg = mir_utf8encodeW(( wchar_t* )&pszSrc[ strlen(pszSrc)+1 ] ); else if ( flags & PREF_UTF ) msg = mir_strdup(pszSrc); else msg = mir_utf8encode(pszSrc); if (lstrlenA(msg) > 800) { ForkThread( &CYahooProto::im_sendackfail_longmsg, hContact ); return 1; } DBVARIANT dbv; if (!getString( hContact, YAHOO_LOGINID, &dbv)) { send_msg(dbv.pszVal, getWord( hContact, "yprotoid", 0), msg, 1); ForkThread( &CYahooProto::im_sendacksuccess, hContact ); db_free(&dbv); return 1; } return 0; }
int CVkProto::SendMsg(HANDLE hContact, int flags, const char *msg) { LONG userID = getDword(hContact, "ID", -1); if (userID == -1) return 0; ptrA szMsg; if (flags & PREF_UTF) szMsg = mir_strdup(msg); else if (flags & PREF_UNICODE) msg = mir_utf8encodeW((wchar_t*)&msg[strlen(msg)+1]); else msg = mir_utf8encode(msg); ULONG msgId = ::InterlockedIncrement(&m_msgId); AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.send.json", true, &CVkProto::OnSendMessage) << INT_PARAM("type", 0) << INT_PARAM("uid", userID) << CHAR_PARAM("message", msg); pReq->pData = (char*)hContact; pReq->pUserInfo = (void*)msgId; Push(pReq); if (!m_bServerDelivery) ForkThread(&CVkProto::SendMsgAck, new TFakeAckParams(hContact, msgId)); return msgId; }
char* TLV::dupw(void) { wchar_t *str = (wchar_t*)part(0, length_); wcs_htons(str); char* stru = mir_utf8encodeW(str); mir_free(str); return stru; }
void CToxPasswordEditor::OnOk(CCtrlButton*) { ptrT tszPassword(password.GetText()); if (savePermanently.Enabled()) m_proto->setTString("Password", tszPassword); if (m_proto->password != NULL) mir_free(m_proto->password); m_proto->password = mir_utf8encodeW(tszPassword); EndDialog(m_hwnd, 1); }
MIRANDA_HOOK_EVENT(ME_DB_EVENT_ADDED, hContact, hDbEvent) { DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(hDbEvent); if (dbei.cbBlob == -1) return 0; dbei.pBlob = (BYTE*)alloca(dbei.cbBlob); db_event_get(hDbEvent, &dbei); // if event is in protocol that is not despammed if (!ProtoInList(dbei.szModule)) return 0; // event is an auth request if (gbHandleAuthReq) { if (!(dbei.flags & DBEF_SENT) && !(dbei.flags & DBEF_READ) && dbei.eventType == EVENTTYPE_AUTHREQUEST) { MCONTACT hcntct = DbGetAuthEventContact(&dbei); // if request is from unknown or not marked Answered contact int a = db_get_b(hcntct, "CList", "NotOnList", 0); int b = !db_get_b(hcntct, pluginName, "Answered", 0); if (a && b) { // ...send message if (gbHideContacts) db_set_b(hcntct, "CList", "Hidden", 1); if (gbSpecialGroup) db_set_ws(hcntct, "CList", "Group", gbSpammersGroup.c_str()); BYTE msg = 1; if (gbIgnoreURL) { TCHAR* EventText = ReqGetText(&dbei); //else return NULL msg = !IsUrlContains(EventText); mir_free(EventText); } if (gbInvisDisable) { if (CallProtoService(dbei.szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE) msg = 0; else if (db_get_w(hContact, dbei.szModule, "ApparentMode", 0) == ID_STATUS_OFFLINE) msg = 0; //is it useful ? } if (msg) { ptrA buff(mir_utf8encodeW(variables_parse(gbAuthRepl, hcntct).c_str())); CallContactService(hcntct, PSS_MESSAGE, 0, (LPARAM)buff); } return 1; } } } return 0; }
int CAimProto::OnDbSettingChanged(WPARAM wParam,LPARAM lParam) { DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; if (strcmp(cws->szModule, MOD_KEY_CL) == 0 && state == 1 && wParam) { HANDLE hContact = (HANDLE)wParam; if (strcmp(cws->szSetting, AIM_KEY_NL) == 0) { if (cws->value.type == DBVT_DELETED) { DBVARIANT dbv; if(!DBGetContactSettingStringUtf(hContact, MOD_KEY_CL, OTH_KEY_GP, &dbv) && dbv.pszVal[0]) { add_contact_to_group(hContact, dbv.pszVal); DBFreeVariant(&dbv); } else add_contact_to_group(hContact, AIM_DEFAULT_GROUP); } } else if (strcmp(cws->szSetting, "MyHandle") == 0) { char* name; switch (cws->value.type) { case DBVT_DELETED: set_local_nick(hContact, NULL, NULL); break; case DBVT_ASCIIZ: name = mir_utf8encode(cws->value.pszVal); set_local_nick(hContact, name, NULL); mir_free(name); break; case DBVT_UTF8: set_local_nick(hContact, cws->value.pszVal, NULL); break; case DBVT_WCHAR: name = mir_utf8encodeW(cws->value.pwszVal); set_local_nick(hContact, name, NULL); mir_free(name); break; } } } return 0; }
static int SettingsChangedHookEventObjParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) { lua_State *L = (lua_State*)obj; int ref = param; lua_rawgeti(L, LUA_REGISTRYINDEX, ref); lua_pushnumber(L, wParam); DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam; lua_newtable(L); lua_pushliteral(L, "Module"); lua_pushstring(L, dbcws->szModule); lua_settable(L, -3); lua_pushliteral(L, "Setting"); lua_pushstring(L, dbcws->szSetting); lua_settable(L, -3); lua_pushliteral(L, "Value"); switch (dbcws->value.type) { case DBVT_BYTE: lua_pushinteger(L, dbcws->value.bVal); break; case DBVT_WORD: lua_pushinteger(L, dbcws->value.wVal); break; case DBVT_DWORD: lua_pushnumber(L, dbcws->value.dVal); break; case DBVT_ASCIIZ: lua_pushstring(L, ptrA(mir_utf8encode(dbcws->value.pszVal))); break; case DBVT_UTF8: lua_pushstring(L, dbcws->value.pszVal); break; case DBVT_WCHAR: lua_pushstring(L, ptrA(mir_utf8encodeW(dbcws->value.pwszVal))); break; default: lua_pushvalue(L, 4); return 1; } lua_settable(L, -3); if (lua_pcall(L, 2, 1, 0)) printf("%s\n", lua_tostring(L, -1)); int res = (int)lua_tointeger(L, 1); return res; }
// outcoming file flow HANDLE CToxProto::OnSendFile(MCONTACT hContact, const TCHAR*, TCHAR **ppszFiles) { int32_t friendNumber = GetToxFriendNumber(hContact); if (friendNumber == UINT32_MAX) return NULL; FILE *hFile = _tfopen(ppszFiles[0], _T("rb")); if (hFile == NULL) { logger->Log(__FUNCTION__": cannot open file %s", ppszFiles[0]); return NULL; } TCHAR *fileName = _tcsrchr(ppszFiles[0], '\\') + 1; size_t fileDirLength = fileName - ppszFiles[0]; TCHAR *fileDir = (TCHAR*)mir_alloc(sizeof(TCHAR)*(fileDirLength + 1)); _tcsncpy(fileDir, ppszFiles[0], fileDirLength); fileDir[fileDirLength] = '\0'; _fseeki64(hFile, 0, SEEK_END); uint64_t fileSize = _ftelli64(hFile); rewind(hFile); char *name = mir_utf8encodeW(fileName); TOX_ERR_FILE_SEND sendError; uint32_t fileNumber = tox_file_send(toxThread->tox, friendNumber, TOX_FILE_KIND_DATA, fileSize, NULL, (uint8_t*)name, mir_strlen(name), &sendError); if (sendError != TOX_ERR_FILE_SEND_OK) { logger->Log(__FUNCTION__": failed to send file (%d) to (%d) cause (%d)", fileNumber, friendNumber, sendError); mir_free(fileDir); mir_free(name); return NULL; } logger->Log(__FUNCTION__": start sending file (%d) to (%d)", fileNumber, friendNumber); FileTransferParam *transfer = new FileTransferParam(friendNumber, fileNumber, fileName, fileSize); transfer->pfts.flags |= PFTS_SENDING; transfer->pfts.hContact = hContact; transfer->pfts.tszWorkingDir = fileDir; transfer->hFile = hFile; transfers.Add(transfer); mir_free(name); return (HANDLE)transfer; }
MIRANDA_HOOK_EVENT(ME_DB_EVENT_ADDED, wParam, lParam) { UNREFERENCED_PARAMETER(wParam); MEVENT hDbEvent = (MEVENT)lParam; DBEVENTINFO dbei = { 0 }; dbei.cbSize = sizeof(dbei); dbei.cbBlob = db_event_getBlobSize(hDbEvent); if (-1 == dbei.cbBlob) return 0; mir_ptr<BYTE> blob((LPBYTE)mir_alloc(dbei.cbBlob)); dbei.pBlob = blob; db_event_get(hDbEvent, &dbei); // if event is in protocol that is not despammed if (plSets->ProtoDisabled(dbei.szModule)) return 0; // event is an auth request if (!(dbei.flags & DBEF_SENT) && !(dbei.flags & DBEF_READ) && dbei.eventType == EVENTTYPE_AUTHREQUEST) { MCONTACT hcntct = DbGetAuthEventContact(&dbei); // if request is from unknown or not marked Answered contact //and if I don't sent message to this contact if (db_get_b(hcntct, "CList", "NotOnList", 0) && !db_get_b(hcntct, pluginName, answeredSetting, 0) && !IsExistMyMessage(hcntct)) { if (!plSets->HandleAuthReq.Get()) { char *buf = mir_utf8encodeW(variables_parse(plSets->AuthRepl.Get(), hcntct).c_str()); CallContactService(hcntct, PSS_MESSAGE, 0, (LPARAM)buf); mir_free(buf); } // ...send message char *AuthRepl = mir_u2a(variables_parse(plSets->AuthRepl.Get(), hcntct).c_str()); CallProtoService(dbei.szModule, PS_AUTHDENY, hDbEvent, (LPARAM)AuthRepl); mir_free(AuthRepl); db_set_b(hcntct, "CList", "NotOnList", 1); db_set_b(hcntct, "CList", "Hidden", 1); if (!plSets->HistLog.Get()) db_event_delete(0, hDbEvent); return 1; } } return 0; }
/** * name: SetName * class: CPsTreeItem * desc: set the unique name for this item from a given title as it comes with OPTIONDIALOGPAGE * param: ptszTitle - the title which is the base for the unique name * bIsUnicode - if TRUE the title is unicode * return: 0 on success, 1 to 4 indicating the failed operation **/ int CPsTreeItem::Name(LPTSTR ptszTitle, const BYTE bIsUnicode) { // convert title to utf8 _pszName = (bIsUnicode) ? mir_utf8encodeW((LPWSTR)ptszTitle) : mir_utf8encode((LPSTR)ptszTitle); if (_pszName) { // convert disallowed characters for (DWORD i = 0; _pszName[i] != 0; i++) { switch (_pszName[i]) { case '{': _pszName[i] = '('; break; case '}': _pszName[i] = ')'; break; } } } return _pszName == NULL; }
static int lua_GetSetting(lua_State *L) { MCONTACT hContact = lua_tointeger(L, 1); LPCSTR szModule = luaL_checkstring(L, 2); LPCSTR szSetting = luaL_checkstring(L, 3); DBVARIANT dbv; if (db_get(hContact, szModule, szSetting, &dbv)) { lua_pushvalue(L, 4); return 1; } switch (dbv.type) { case DBVT_BYTE: lua_pushinteger(L, dbv.bVal); break; case DBVT_WORD: lua_pushinteger(L, dbv.wVal); break; case DBVT_DWORD: lua_pushnumber(L, dbv.dVal); break; case DBVT_ASCIIZ: lua_pushstring(L, ptrA(mir_utf8encode(dbv.pszVal))); break; case DBVT_UTF8: lua_pushstring(L, dbv.pszVal); break; case DBVT_WCHAR: lua_pushstring(L, ptrA(mir_utf8encodeW(dbv.pwszVal))); break; default: db_free(&dbv); lua_pushvalue(L, 4); return 1; } db_free(&dbv); return 1; }
int __cdecl CYahooProto::SendMsg( HANDLE hContact, int flags, const char* pszSrc ) { DBVARIANT dbv; char *msg; int bANSI; bANSI = 0;/*GetByte( "DisableUTF8", 0 );*/ if (!m_bLoggedIn) {/* don't send message if we not connected! */ YForkThread( &CYahooProto::im_sendackfail, hContact ); return 1; } if (bANSI) /* convert to ANSI */ msg = ( char* )pszSrc; else if ( flags & PREF_UNICODE ) /* convert to utf8 */ msg = mir_utf8encodeW(( wchar_t* )&pszSrc[ strlen(pszSrc)+1 ] ); else if ( flags & PREF_UTF ) msg = mir_strdup(( char* )pszSrc ); else msg = mir_utf8encode(( char* )pszSrc ); if (lstrlenA(msg) > 800) { YForkThread( &CYahooProto::im_sendackfail_longmsg, hContact ); return 1; } if (!DBGetContactSettingString( hContact, m_szModuleName, YAHOO_LOGINID, &dbv)) { send_msg(dbv.pszVal, GetWord( hContact, "yprotoid", 0), msg, (!bANSI) ? 1 : 0); if (!bANSI) mir_free(msg); YForkThread( &CYahooProto::im_sendacksuccess, hContact ); DBFreeVariant(&dbv); return 1; } return 0; }
static int lua_DecodeDBCONTACTWRITESETTING(lua_State *L) { ObsoleteMethod(L, "Use totable(x, \"DBCONTACTWRITESETTING\") instead"); DBCONTACTWRITESETTING *pDBCWS = (DBCONTACTWRITESETTING*)lua_tointeger(L, 1); lua_newtable(L); lua_pushliteral(L, "Module"); lua_pushstring(L, pDBCWS->szModule); lua_settable(L, -3); lua_pushliteral(L, "Setting"); lua_pushstring(L, pDBCWS->szSetting); lua_settable(L, -3); lua_pushliteral(L, "Value"); switch (pDBCWS->value.type) { case DBVT_BYTE: lua_pushinteger(L, pDBCWS->value.bVal); break; case DBVT_WORD: lua_pushinteger(L, pDBCWS->value.wVal); break; case DBVT_DWORD: lua_pushnumber(L, pDBCWS->value.dVal); break; case DBVT_ASCIIZ: lua_pushstring(L, ptrA(mir_utf8encode(pDBCWS->value.pszVal))); break; case DBVT_UTF8: lua_pushstring(L, pDBCWS->value.pszVal); break; case DBVT_WCHAR: lua_pushstring(L, ptrA(mir_utf8encodeW(pDBCWS->value.pwszVal))); break; default: lua_pushvalue(L, 4); return 1; } lua_settable(L, -3); return 1; }
void CToxProto::SaveToxProfile(CToxThread *toxThread) { mir_cslock locker(profileLock); if (!toxThread) return; size_t size = tox_get_savedata_size(toxThread->Tox()); uint8_t *data = (uint8_t*)mir_calloc(size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH); tox_get_savedata(toxThread->Tox(), data); pass_ptrA password(mir_utf8encodeW(pass_ptrT(getTStringA("Password")))); if (password && mir_strlen(password)) { TOX_ERR_ENCRYPTION coreEncryptError; if (!tox_pass_encrypt(data, size, (uint8_t*)(char*)password, mir_strlen(password), data, &coreEncryptError)) { debugLogA(__FUNCTION__": failed to encrypt tox profile"); mir_free(data); return; } size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; } ptrT profilePath(GetToxProfilePath()); FILE *profile = _tfopen(profilePath, _T("wb")); if (profile == NULL) { debugLogA(__FUNCTION__": failed to open tox profile"); mir_free(data); return; } size_t written = fwrite(data, sizeof(char), size, profile); if (size != written) { debugLogA(__FUNCTION__": failed to write tox profile"); } fclose(profile); mir_free(data); }
static int dbcw__index(lua_State *L) { DBCONTACTWRITESETTING *dbcw = (DBCONTACTWRITESETTING*)luaL_checkudata(L, 1, MT_DBCONTACTWRITESETTING); const char *key = luaL_checkstring(L, 2); if (mir_strcmpi(key, "Module") == 0) lua_pushstring(L, dbcw->szModule); else if (mir_strcmpi(key, "Setting") == 0) lua_pushstring(L, dbcw->szSetting); else if (mir_strcmpi(key, "Value") == 0) { switch (dbcw->value.type) { case DBVT_BYTE: lua_pushinteger(L, dbcw->value.bVal); break; case DBVT_WORD: lua_pushinteger(L, dbcw->value.wVal); break; case DBVT_DWORD: lua_pushnumber(L, dbcw->value.dVal); break; case DBVT_ASCIIZ: lua_pushstring(L, ptrA(mir_utf8encode(dbcw->value.pszVal))); break; case DBVT_UTF8: lua_pushstring(L, dbcw->value.pszVal); break; case DBVT_WCHAR: lua_pushstring(L, ptrA(mir_utf8encodeW(dbcw->value.pwszVal))); break; default: lua_pushnil(L); } } else lua_pushnil(L); return 1; }
int GGPROTO::SendMsg(HANDLE hContact, int flags, const char *msg) { uin_t uin = (uin_t)getDword(hContact, GG_KEY_UIN, 0); if (!isonline() || !uin) return 0; char* msg_utf8; if (flags & PREF_UNICODE) msg_utf8 = mir_utf8encodeW((wchar_t*)&msg[ strlen( msg )+1 ] ); else if (flags & PREF_UTF) msg_utf8 = mir_strdup(msg); else msg_utf8 = mir_utf8encode(msg); if (!msg_utf8) return 0; gg_EnterCriticalSection(&sess_mutex, "SendMsg", 53, "sess_mutex", 1); int seq = gg_send_message(sess, GG_CLASS_CHAT, uin, (BYTE*)msg_utf8); gg_LeaveCriticalSection(&sess_mutex, "SendMsg", 53, 1, "sess_mutex", 1); if (!getByte(GG_KEY_MSGACK, GG_KEYDEF_MSGACK)) { // Auto-ack message without waiting for server ack GG_SEQ_ACK *ack = (GG_SEQ_ACK*)mir_alloc(sizeof(GG_SEQ_ACK)); if (ack) { ack->seq = seq; ack->hContact = hContact; #ifdef DEBUGMODE debugLogA("SendMsg(): ForkThread 16 GGPROTO::sendackthread"); #endif ForkThread(&GGPROTO::sendackthread, ack); } } mir_free(msg_utf8); return seq; }
void MirandaUtils::sendMessage(ActionThreadArgStruct* args, MFENUM_SEND_MESSAGE_MODE mode) { logger->log_p(L"MirandaUtils::sendMessage: mode = [%d] to = [" SCNuPTR L"] msg = [%s]", mode, args->targetHandle, args->userActionSelection ); if (mode == MFENUM_SMM_ONLY_SEND || mode == MFENUM_SMM_SEND_AND_SHOW_MW){ //TODO - metacontacts support - C:\MIRANDA\SOURCES\PLUGINS\popup_trunk\src\popup_wnd2.cpp : 1083 // //check for MetaContact and get szProto from subcontact // if(strcmp(targetHandleSzProto, gszMetaProto)==0) { // HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT, (WPARAM)hContact, 0); // if(!hSubContact) return FALSE; // targetHandleSzProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hSubContact, 0); // } char* targetHandleSzProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)args->targetHandle, 0); //targetHandleSzProto doesnt need mir_free or delete if (targetHandleSzProto == NULL){ logger->log(L"MirandaUtils::sendMessageToContact: ERROR targetHandleSzProto == NULL"); return; } int mirandaSendModeFlag = getMirandaSendModeFlag(targetHandleSzProto); char* msgBuffer = NULL; std::size_t bufSize = 0; if (mirandaSendModeFlag == PREF_UTF){ msgBuffer = mir_utf8encodeW(args->userActionSelection); bufSize = strlen(msgBuffer) + 1; } else if (mirandaSendModeFlag == PREF_UNICODE){ msgBuffer = mir_t2a(args->userActionSelection); bufSize = strlen(msgBuffer) + 1; size_t bufSizeT = (wcslen(args->userActionSelection) + 1) * sizeof(wchar_t); msgBuffer = (char*)mir_realloc(msgBuffer, bufSizeT + bufSize); memcpy((wchar_t*)&msgBuffer[bufSize], args->userActionSelection, bufSizeT); bufSize += bufSizeT; } logger->log_p(L"SMTC: mirandaSendModeFlag = [%d] bufSize = [%d]", mirandaSendModeFlag, bufSize); HANDLE hProcess = sendMessageMiranda(args->targetHandle, mirandaSendModeFlag, msgBuffer); logger->log_p(L"SMTC: hProcess = [" SCNuPTR L"]", hProcess); MIRFOXACKDATA* myMfAck = NULL; if (hProcess != NULL){ //if hProcess of sending process is null there will not be any ack EnterCriticalSection(&ackMapCs); ackMap[hProcess] = (MIRFOXACKDATA*)NULL; LeaveCriticalSection(&ackMapCs); int counter = 0; const int ACK_WAIT_TIME = 250; //[ms] const int MAX_ACK_WAIT_COUNTER = 40; //40 * 250ms = 10s do { SleepEx(ACK_WAIT_TIME, TRUE); counter++; EnterCriticalSection(&ackMapCs); myMfAck = ackMap[hProcess]; LeaveCriticalSection(&ackMapCs); if(Miranda_Terminated() || args->mirfoxDataPtr->Plugin_Terminated){ logger->log_p(L"SMTC: ACK break by Plugin_Terminated (=%d) or Miranda_Terminated()", args->mirfoxDataPtr->Plugin_Terminated); break; } } while (myMfAck == NULL && counter <= MAX_ACK_WAIT_COUNTER); //TODO or Plugin_Terminated or Miranda_Terminated() logger->log_p(L"SMTC: ACK found counter = [%d] myMfAck = [" SCNuPTR L"]", counter, myMfAck); } MirandaContact* mirandaContact = args->mirfoxDataPtr->getMirandaContactPtrByHandle(args->targetHandle); const wchar_t* contactNameW = NULL; TCHAR* tszAccountName = NULL; if (mirandaContact){ contactNameW = mirandaContact->contactNameW.c_str(); MirandaAccount* mirandaAccount = mirandaContact->mirandaAccountPtr; if (mirandaAccount){ tszAccountName = mirandaAccount->tszAccountName; } } if(myMfAck != NULL && myMfAck->result == ACKRESULT_SUCCESS){ addMessageToDB(args->targetHandle, mirandaSendModeFlag, msgBuffer, bufSize, targetHandleSzProto); if (mode == MFENUM_SMM_ONLY_SEND){ //show notyfication popup (only in SMM_ONLY_SEND mode) wchar_t* buffer = new wchar_t[1024 * sizeof(wchar_t)]; if (contactNameW != NULL && tszAccountName != NULL){ mir_sntprintf(buffer, 1024, TranslateT("Message sent to %s (%s)"), contactNameW, tszAccountName); } else { buffer = mir_wstrdup(TranslateT("Message sent")); } if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) { ShowClassPopupT("MirFox_Notify", TranslateT("MirFox"), buffer); } else { PUShowMessageT(buffer, SM_NOTIFY); } delete buffer; } else if (mode == MFENUM_SMM_SEND_AND_SHOW_MW){ //notify hook to open window if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){ OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct); onHookOpenMv->targetHandle = args->targetHandle; onHookOpenMv->msgBuffer = NULL; NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, (LPARAM)NULL); } else { logger->log(L"SMTC: ERROR1 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL"); } } } else { //error - show error popup wchar_t* buffer = new wchar_t[1024 * sizeof(wchar_t)]; if (myMfAck != NULL){ logger->log_p(L"SMTC: ERROR - Cannot send message - result = [%d] ", myMfAck->result); if (myMfAck->errorDesc != NULL){ if (contactNameW != NULL && tszAccountName != NULL){ mir_sntprintf(buffer, 1024, TranslateT("Cannot send message to %s (%s) - %S"), contactNameW, tszAccountName, myMfAck->errorDesc); } else { mir_sntprintf(buffer, 1024, TranslateT("Cannot send message - %S"), myMfAck->errorDesc); } } else { if (contactNameW != NULL && tszAccountName != NULL){ mir_sntprintf(buffer, 1024, TranslateT("Cannot send message to %s (%s)"), contactNameW, tszAccountName); } else { buffer = mir_wstrdup(TranslateT("Cannot send message - %S")); } } } else { logger->log(L"SMTC: ERROR - Cannot send message 2"); if (contactNameW != NULL && tszAccountName != NULL){ mir_sntprintf(buffer, 1024, TranslateT("Cannot send message to %s (%s)"), contactNameW, tszAccountName); } else { buffer = mir_wstrdup(TranslateT("Cannot send message")); } } if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) { ShowClassPopupT("MirFox_Error", TranslateT("MirFox error"), buffer); } else { PUShowMessageT(buffer, SM_WARNING); } delete buffer; } if (myMfAck != NULL){ //when we found ack, not when we exceed MAX_ACK_WAIT_COUNTER if (myMfAck->errorDesc != NULL) delete myMfAck->errorDesc; delete myMfAck->szModule; delete myMfAck; } EnterCriticalSection(&ackMapCs); ackMap.erase(hProcess); LeaveCriticalSection(&ackMapCs); mir_free(msgBuffer); } else if (mode == MFENUM_SMM_ONLY_SHOW_MW){ //notify hook to open window if (args->mirfoxDataPtr != NULL && args->mirfoxDataPtr->hhook_EventOpenMW != NULL){ OnHookOpenMvStruct* onHookOpenMv = new(OnHookOpenMvStruct); onHookOpenMv->targetHandle = args->targetHandle; //adding newline to message in Message Window, only in this mode std::wstring* msgBuffer = new std::wstring(); //deleted at on_hook_OpenMW msgBuffer->append(args->userActionSelection); msgBuffer->append(L"\r\n"); onHookOpenMv->msgBuffer = msgBuffer; NotifyEventHooks(args->mirfoxDataPtr->hhook_EventOpenMW, (WPARAM)onHookOpenMv, (LPARAM)NULL); } else { logger->log(L"SMTC: ERROR1 args->mirfoxDataPtr == NULL || args->mirfoxDataPtr->hhook_EventOpenMW == NULL"); } } }
STDMETHODIMP_(BOOL) CDb3Mmap::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws) { if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL || m_bReadOnly) return 1; // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name int settingNameLen = (int)mir_strlen(dbcws->szSetting); int moduleNameLen = (int)mir_strlen(dbcws->szModule); if (settingNameLen > 0xFE) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); #endif return 1; } if (moduleNameLen > 0xFE) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); #endif return 1; } // used for notifications DBCONTACTWRITESETTING dbcwNotif = *dbcws; if (dbcwNotif.value.type == DBVT_WCHAR) { if (dbcwNotif.value.pszVal != NULL) { char* val = mir_utf8encodeW(dbcwNotif.value.pwszVal); if (val == NULL) return 1; dbcwNotif.value.pszVal = (char*)alloca(mir_strlen(val) + 1); mir_strcpy(dbcwNotif.value.pszVal, val); mir_free(val); dbcwNotif.value.type = DBVT_UTF8; } else return 1; } if (dbcwNotif.szModule == NULL || dbcwNotif.szSetting == NULL) return 1; DBCONTACTWRITESETTING dbcwWork = dbcwNotif; mir_ptr<BYTE> pEncoded(NULL); bool bIsEncrypted = false; switch (dbcwWork.value.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: break; case DBVT_ASCIIZ: case DBVT_UTF8: bIsEncrypted = m_bEncrypted || IsSettingEncrypted(dbcws->szModule, dbcws->szSetting); LBL_WriteString: if (dbcwWork.value.pszVal == NULL) return 1; dbcwWork.value.cchVal = (WORD)mir_strlen(dbcwWork.value.pszVal); if (bIsEncrypted) { size_t len; BYTE *pResult = m_crypto->encodeString(dbcwWork.value.pszVal, &len); if (pResult != NULL) { pEncoded = dbcwWork.value.pbVal = pResult; dbcwWork.value.cpbVal = (WORD)len; dbcwWork.value.type = DBVT_ENCRYPTED; } } break; case DBVT_UNENCRYPTED: dbcwNotif.value.type = dbcwWork.value.type = DBVT_UTF8; goto LBL_WriteString; case DBVT_BLOB: case DBVT_ENCRYPTED: if (dbcwWork.value.pbVal == NULL) return 1; break; default: return 1; } mir_cslockfull lck(m_csDbAccess); DWORD ofsBlobPtr, ofsContact = GetContactOffset(contactID); if (ofsContact == 0) { _ASSERT(false); // contact doesn't exist? return 2; } char *szCachedSettingName = m_cache->GetCachedSetting(dbcwWork.szModule, dbcwWork.szSetting, moduleNameLen, settingNameLen); log3("set [%08p] %s (%p)", hContact, szCachedSettingName, szCachedSettingName); // we don't cache blobs and passwords if (dbcwWork.value.type != DBVT_BLOB && dbcwWork.value.type != DBVT_ENCRYPTED && !bIsEncrypted) { DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1); if (pCachedValue != NULL) { bool bIsIdentical = false; if (pCachedValue->type == dbcwWork.value.type) { switch (dbcwWork.value.type) { case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcwWork.value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcwWork.value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcwWork.value.dVal; break; case DBVT_UTF8: case DBVT_ASCIIZ: bIsIdentical = mir_strcmp(pCachedValue->pszVal, dbcwWork.value.pszVal) == 0; break; } if (bIsIdentical) return 0; } m_cache->SetCachedVariant(&dbcwWork.value, pCachedValue); } if (szCachedSettingName[-1] != 0) { lck.unlock(); log2(" set resident as %s (%p)", printVariant(&dbcwWork.value), pCachedValue); NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwWork); return 0; } } else m_cache->GetCachedValuePtr(contactID, szCachedSettingName, -1); log1(" write database as %s", printVariant(&dbcwWork.value)); DWORD ofsModuleName = GetModuleNameOfs(dbcwWork.szModule); DBContact dbc = *(DBContact*)DBRead(ofsContact, NULL); if (dbc.signature != DBCONTACT_SIGNATURE) return 1; // make sure the module group exists PBYTE pBlob; int bytesRequired, bytesRemaining; DBContactSettings dbcs; DWORD ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(&dbc, ofsModuleName); if (ofsSettingsGroup == 0) { //module group didn't exist - make it switch (dbcwWork.value.type) { case DBVT_ASCIIZ: case DBVT_UTF8: bytesRequired = dbcwWork.value.cchVal + 2; break; case DBVT_BLOB: case DBVT_ENCRYPTED: bytesRequired = dbcwWork.value.cpbVal + 2; break; default: bytesRequired = dbcwWork.value.type; } bytesRequired += 2 + settingNameLen; bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY - (bytesRequired % DB_SETTINGS_RESIZE_GRANULARITY)) % DB_SETTINGS_RESIZE_GRANULARITY; ofsSettingsGroup = CreateNewSpace(bytesRequired + offsetof(DBContactSettings, blob)); dbcs.signature = DBCONTACTSETTINGS_SIGNATURE; dbcs.ofsNext = dbc.ofsFirstSettings; dbcs.ofsModuleName = ofsModuleName; dbcs.cbBlob = bytesRequired; dbcs.blob[0] = 0; dbc.ofsFirstSettings = ofsSettingsGroup; DBWrite(ofsContact, &dbc, sizeof(DBContact)); DBWrite(ofsSettingsGroup, &dbcs, sizeof(DBContactSettings)); ofsBlobPtr = ofsSettingsGroup + offsetof(DBContactSettings, blob); pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); } else { dbcs = *(DBContactSettings*)DBRead(ofsSettingsGroup, &bytesRemaining); // find if the setting exists ofsBlobPtr = ofsSettingsGroup + offsetof(DBContactSettings, blob); pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); while (pBlob[0]) { NeedBytes(settingNameLen + 1); if (pBlob[0] == settingNameLen && !memcmp(pBlob + 1, dbcwWork.szSetting, settingNameLen)) break; NeedBytes(1); MoveAlong(pBlob[0] + 1); NeedBytes(3); MoveAlong(1 + GetSettingValueLength(pBlob)); NeedBytes(1); } // setting already existed, and up to end of name is in cache if (pBlob[0]) { MoveAlong(1 + settingNameLen); // if different type or variable length and length is different NeedBytes(3); if (pBlob[0] != dbcwWork.value.type || ((pBlob[0] == DBVT_ASCIIZ || pBlob[0] == DBVT_UTF8) && *(PWORD)(pBlob + 1) != dbcwWork.value.cchVal) || ((pBlob[0] == DBVT_BLOB || pBlob[0] == DBVT_ENCRYPTED) && *(PWORD)(pBlob + 1) != dbcwWork.value.cpbVal)) { // bin it NeedBytes(3); int nameLen = 1 + settingNameLen; int valLen = 1 + GetSettingValueLength(pBlob); DWORD ofsSettingToCut = ofsBlobPtr - nameLen; MoveAlong(valLen); NeedBytes(1); while (pBlob[0]) { MoveAlong(pBlob[0] + 1); NeedBytes(3); MoveAlong(1 + GetSettingValueLength(pBlob)); NeedBytes(1); } DBMoveChunk(ofsSettingToCut, ofsSettingToCut + nameLen + valLen, ofsBlobPtr + 1 - ofsSettingToCut); ofsBlobPtr -= nameLen + valLen; pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); } else { // replace existing setting at pBlob MoveAlong(1); // skip data type switch (dbcwWork.value.type) { case DBVT_BYTE: DBWrite(ofsBlobPtr, &dbcwWork.value.bVal, 1); break; case DBVT_WORD: DBWrite(ofsBlobPtr, &dbcwWork.value.wVal, 2); break; case DBVT_DWORD: DBWrite(ofsBlobPtr, &dbcwWork.value.dVal, 4); break; case DBVT_BLOB: DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); break; case DBVT_ENCRYPTED: DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); break; case DBVT_UTF8: case DBVT_ASCIIZ: DBWrite(ofsBlobPtr + 2, dbcwWork.value.pszVal, dbcwWork.value.cchVal); break; } // quit DBFlush(1); lck.unlock(); // notify NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif); return 0; } } } // cannot do a simple replace, add setting to end of list // pBlob already points to end of list // see if it fits switch (dbcwWork.value.type) { case DBVT_ASCIIZ: case DBVT_UTF8: bytesRequired = dbcwWork.value.cchVal + 2; break; case DBVT_BLOB: case DBVT_ENCRYPTED: bytesRequired = dbcwWork.value.cpbVal + 2; break; default: bytesRequired = dbcwWork.value.type; } bytesRequired += 2 + settingNameLen; bytesRequired += ofsBlobPtr + 1 - (ofsSettingsGroup + offsetof(DBContactSettings, blob)); if ((DWORD)bytesRequired > dbcs.cbBlob) { // doesn't fit: move entire group DBContactSettings *dbcsPrev; DWORD ofsDbcsPrev, ofsNew; InvalidateSettingsGroupOfsCacheEntry(ofsSettingsGroup); bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY - (bytesRequired % DB_SETTINGS_RESIZE_GRANULARITY)) % DB_SETTINGS_RESIZE_GRANULARITY; // find previous group to change its offset ofsDbcsPrev = dbc.ofsFirstSettings; if (ofsDbcsPrev == ofsSettingsGroup) ofsDbcsPrev = 0; else { dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev, NULL); while (dbcsPrev->ofsNext != ofsSettingsGroup) { if (dbcsPrev->ofsNext == 0) DatabaseCorruption(NULL); ofsDbcsPrev = dbcsPrev->ofsNext; dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev, NULL); } } // create the new one ofsNew = ReallocSpace(ofsSettingsGroup, dbcs.cbBlob + offsetof(DBContactSettings, blob), bytesRequired + offsetof(DBContactSettings, blob)); dbcs.cbBlob = bytesRequired; DBWrite(ofsNew, &dbcs, offsetof(DBContactSettings, blob)); if (ofsDbcsPrev == 0) { dbc.ofsFirstSettings = ofsNew; DBWrite(ofsContact, &dbc, sizeof(DBContact)); } else { dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev, NULL); dbcsPrev->ofsNext = ofsNew; DBWrite(ofsDbcsPrev, dbcsPrev, offsetof(DBContactSettings, blob)); } ofsBlobPtr += ofsNew - ofsSettingsGroup; ofsSettingsGroup = ofsNew; pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); } // we now have a place to put it and enough space: make it DBWrite(ofsBlobPtr, &settingNameLen, 1); DBWrite(ofsBlobPtr + 1, (PVOID)dbcwWork.szSetting, settingNameLen); MoveAlong(1 + settingNameLen); DBWrite(ofsBlobPtr, &dbcwWork.value.type, 1); MoveAlong(1); switch (dbcwWork.value.type) { case DBVT_BYTE: DBWrite(ofsBlobPtr, &dbcwWork.value.bVal, 1); MoveAlong(1); break; case DBVT_WORD: DBWrite(ofsBlobPtr, &dbcwWork.value.wVal, 2); MoveAlong(2); break; case DBVT_DWORD: DBWrite(ofsBlobPtr, &dbcwWork.value.dVal, 4); MoveAlong(4); break; case DBVT_BLOB: DBWrite(ofsBlobPtr, &dbcwWork.value.cpbVal, 2); DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); MoveAlong(2 + dbcwWork.value.cpbVal); break; case DBVT_ENCRYPTED: DBWrite(ofsBlobPtr, &dbcwWork.value.cpbVal, 2); DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); MoveAlong(2 + dbcwWork.value.cpbVal); break; case DBVT_UTF8: case DBVT_ASCIIZ: DBWrite(ofsBlobPtr, &dbcwWork.value.cchVal, 2); DBWrite(ofsBlobPtr + 2, dbcwWork.value.pszVal, dbcwWork.value.cchVal); MoveAlong(2 + dbcwWork.value.cchVal); break; } BYTE zero = 0; DBWrite(ofsBlobPtr, &zero, 1); // quit DBFlush(1); lck.unlock(); // notify NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif); return 0; }
STDMETHODIMP_(BOOL) CDbxKV::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws) { if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL || m_bReadOnly) return 1; // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name int settingNameLen = (int)strlen(dbcws->szSetting); int moduleNameLen = (int)strlen(dbcws->szModule); if (settingNameLen > 0xFE) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); #endif return 1; } if (moduleNameLen > 0xFE) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); #endif return 1; } // used for notifications DBCONTACTWRITESETTING dbcwNotif = *dbcws; if (dbcwNotif.value.type == DBVT_WCHAR) { if (dbcwNotif.value.pszVal != NULL) { char* val = mir_utf8encodeW(dbcwNotif.value.pwszVal); if (val == NULL) return 1; dbcwNotif.value.pszVal = (char*)alloca(strlen(val) + 1); strcpy(dbcwNotif.value.pszVal, val); mir_free(val); dbcwNotif.value.type = DBVT_UTF8; } else return 1; } if (dbcwNotif.szModule == NULL || dbcwNotif.szSetting == NULL) return 1; DBCONTACTWRITESETTING dbcwWork = dbcwNotif; mir_ptr<BYTE> pEncoded(NULL); bool bIsEncrypted = false; switch (dbcwWork.value.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: break; case DBVT_ASCIIZ: case DBVT_UTF8: bIsEncrypted = m_bEncrypted || IsSettingEncrypted(dbcws->szModule, dbcws->szSetting); LBL_WriteString: if (dbcwWork.value.pszVal == NULL) return 1; dbcwWork.value.cchVal = (WORD)strlen(dbcwWork.value.pszVal); if (bIsEncrypted) { size_t len; BYTE *pResult = m_crypto->encodeString(dbcwWork.value.pszVal, &len); if (pResult != NULL) { pEncoded = dbcwWork.value.pbVal = pResult; dbcwWork.value.cpbVal = (WORD)len; dbcwWork.value.type = DBVT_ENCRYPTED; } } break; case DBVT_UNENCRYPTED: dbcwNotif.value.type = dbcwWork.value.type = DBVT_UTF8; goto LBL_WriteString; case DBVT_BLOB: case DBVT_ENCRYPTED: if (dbcwWork.value.pbVal == NULL) return 1; break; default: return 1; } mir_cslockfull lck(m_csDbAccess); char *szCachedSettingName = m_cache->GetCachedSetting(dbcwWork.szModule, dbcwWork.szSetting, moduleNameLen, settingNameLen); // we don't cache blobs and passwords if (dbcwWork.value.type != DBVT_BLOB && dbcwWork.value.type != DBVT_ENCRYPTED && !bIsEncrypted) { DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1); if (pCachedValue != NULL) { bool bIsIdentical = false; if (pCachedValue->type == dbcwWork.value.type) { switch (dbcwWork.value.type) { case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcwWork.value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcwWork.value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcwWork.value.dVal; break; case DBVT_UTF8: case DBVT_ASCIIZ: bIsIdentical = strcmp(pCachedValue->pszVal, dbcwWork.value.pszVal) == 0; break; } if (bIsIdentical) return 0; } m_cache->SetCachedVariant(&dbcwWork.value, pCachedValue); } if (szCachedSettingName[-1] != 0) { lck.unlock(); NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwWork); return 0; } } else m_cache->GetCachedValuePtr(contactID, szCachedSettingName, -1); DBSettingSortingKey keySearch; keySearch.dwContactID = contactID; keySearch.dwOfsModule = GetModuleNameOfs(dbcws->szModule); strncpy_s(keySearch.szSettingName, dbcws->szSetting, _TRUNCATE); ham_key_t key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch }; ham_record_t rec = { 0 }; switch (dbcwWork.value.type) { case DBVT_BYTE: rec.size = 2; break; case DBVT_WORD: rec.size = 3; break; case DBVT_DWORD: rec.size = 5; break; case DBVT_ASCIIZ: case DBVT_UTF8: rec.size = 3 + dbcwWork.value.cchVal; break; case DBVT_BLOB: case DBVT_ENCRYPTED: rec.size = 3 + dbcwWork.value.cpbVal; break; default: return 1; } rec.data = _alloca(rec.size); BYTE *pBlob = (BYTE*)rec.data; *pBlob++ = dbcwWork.value.type; switch (dbcwWork.value.type) { case DBVT_BYTE: *pBlob = dbcwWork.value.bVal; break; case DBVT_WORD: *(WORD*)pBlob = dbcwWork.value.wVal; break; case DBVT_DWORD: *(DWORD*)pBlob = dbcwWork.value.dVal; break; case DBVT_ASCIIZ: case DBVT_UTF8: *(WORD*)pBlob = dbcwWork.value.cchVal; memcpy(pBlob+2, dbcwWork.value.pszVal, dbcwWork.value.cchVal); break; case DBVT_BLOB: case DBVT_ENCRYPTED: *(WORD*)pBlob = dbcwWork.value.cpbVal; memcpy(pBlob+2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); } ham_db_insert(m_dbSettings, NULL, &key, &rec, HAM_OVERWRITE); lck.unlock(); // notify NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif); return 0; }
void NLog(wchar_t *msg) { char* a = mir_utf8encodeW(msg); CallService(MS_NETLIB_LOG, (WPARAM)hNetlibUser, (LPARAM)a); mir_free(a); }
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; }
STDMETHODIMP_(BOOL) CDbxMdb::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws) { if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL || m_bReadOnly) return 1; // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name int settingNameLen = (int)strlen(dbcws->szSetting); int moduleNameLen = (int)strlen(dbcws->szModule); // used for notifications DBCONTACTWRITESETTING dbcwNotif = *dbcws; if (dbcwNotif.value.type == DBVT_WCHAR) { if (dbcwNotif.value.pszVal != NULL) { char* val = mir_utf8encodeW(dbcwNotif.value.pwszVal); if (val == NULL) return 1; dbcwNotif.value.pszVal = (char*)alloca(strlen(val) + 1); strcpy(dbcwNotif.value.pszVal, val); mir_free(val); dbcwNotif.value.type = DBVT_UTF8; } else return 1; } if (dbcwNotif.szModule == NULL || dbcwNotif.szSetting == NULL) return 1; DBCONTACTWRITESETTING dbcwWork = dbcwNotif; mir_ptr<BYTE> pEncoded(NULL); bool bIsEncrypted = false; switch (dbcwWork.value.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: break; case DBVT_ASCIIZ: case DBVT_UTF8: bIsEncrypted = m_bEncrypted || IsSettingEncrypted(dbcws->szModule, dbcws->szSetting); LBL_WriteString: if (dbcwWork.value.pszVal == NULL) return 1; dbcwWork.value.cchVal = (WORD)strlen(dbcwWork.value.pszVal); if (bIsEncrypted) { size_t len; BYTE *pResult = m_crypto->encodeString(dbcwWork.value.pszVal, &len); if (pResult != NULL) { pEncoded = dbcwWork.value.pbVal = pResult; dbcwWork.value.cpbVal = (WORD)len; dbcwWork.value.type = DBVT_ENCRYPTED; } } break; case DBVT_UNENCRYPTED: dbcwNotif.value.type = dbcwWork.value.type = DBVT_UTF8; goto LBL_WriteString; case DBVT_BLOB: case DBVT_ENCRYPTED: if (dbcwWork.value.pbVal == NULL) return 1; break; default: return 1; } mir_cslockfull lck(m_csDbAccess); char *szCachedSettingName = m_cache->GetCachedSetting(dbcwWork.szModule, dbcwWork.szSetting, moduleNameLen, settingNameLen); // we don't cache blobs and passwords if (dbcwWork.value.type != DBVT_BLOB && dbcwWork.value.type != DBVT_ENCRYPTED && !bIsEncrypted) { DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1); if (pCachedValue != NULL) { bool bIsIdentical = false; if (pCachedValue->type == dbcwWork.value.type) { switch (dbcwWork.value.type) { case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcwWork.value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcwWork.value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcwWork.value.dVal; break; case DBVT_UTF8: case DBVT_ASCIIZ: bIsIdentical = strcmp(pCachedValue->pszVal, dbcwWork.value.pszVal) == 0; break; } if (bIsIdentical) return 0; } m_cache->SetCachedVariant(&dbcwWork.value, pCachedValue); } if (szCachedSettingName[-1] != 0) { lck.unlock(); NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwWork); return 0; } } else m_cache->GetCachedValuePtr(contactID, szCachedSettingName, -1); DBSettingKey keySearch; keySearch.dwContactID = contactID; keySearch.dwOfsModule = GetModuleNameOfs(dbcws->szModule); strncpy_s(keySearch.szSettingName, dbcws->szSetting, _TRUNCATE); MDB_val key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch }, data; switch (dbcwWork.value.type) { case DBVT_BYTE: data.mv_size = 2; break; case DBVT_WORD: data.mv_size = 3; break; case DBVT_DWORD: data.mv_size = 5; break; case DBVT_ASCIIZ: case DBVT_UTF8: data.mv_size = 3 + dbcwWork.value.cchVal; break; case DBVT_BLOB: case DBVT_ENCRYPTED: data.mv_size = 3 + dbcwWork.value.cpbVal; break; } for (;; Remap()) { txn_ptr trnlck(m_pMdbEnv); MDB_CHECK(mdb_put(trnlck, m_dbSettings, &key, &data, MDB_RESERVE), 1); BYTE *pBlob = (BYTE*)data.mv_data; *pBlob++ = dbcwWork.value.type; switch (dbcwWork.value.type) { case DBVT_BYTE: *pBlob = dbcwWork.value.bVal; break; case DBVT_WORD: *(WORD*)pBlob = dbcwWork.value.wVal; break; case DBVT_DWORD: *(DWORD*)pBlob = dbcwWork.value.dVal; break; case DBVT_ASCIIZ: case DBVT_UTF8: data.mv_size = *(WORD*)pBlob = dbcwWork.value.cchVal; pBlob += 2; memcpy(pBlob, dbcwWork.value.pszVal, dbcwWork.value.cchVal); break; case DBVT_BLOB: case DBVT_ENCRYPTED: data.mv_size = *(WORD*)pBlob = dbcwWork.value.cpbVal; pBlob += 2; memcpy(pBlob, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); } if (trnlck.commit()) break; } lck.unlock(); // notify NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif); return 0; }
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; }
bool CToxProto::LoadToxProfile(Tox_Options *options) { debugLogA(__FUNCTION__": loading tox profile"); mir_cslock locker(profileLock); ptrT profilePath(GetToxProfilePath()); if (!IsFileExists(profilePath)) return false; FILE *profile = _tfopen(profilePath, _T("rb")); if (profile == NULL) { ShowNotification(TranslateT("Unable to open Tox profile"), MB_ICONERROR); debugLogA(__FUNCTION__": failed to open tox profile"); return false; } fseek(profile, 0, SEEK_END); long size = ftell(profile); rewind(profile); if (size < 0) { fclose(profile); return false; } if (size == 0) { fclose(profile); return true; } uint8_t *data = (uint8_t*)mir_calloc(size); if (fread((char*)data, sizeof(char), size, profile) != (size_t)size) { fclose(profile); ShowNotification(TranslateT("Unable to read Tox profile"), MB_ICONERROR); debugLogA(__FUNCTION__": failed to read tox profile"); mir_free(data); return false; } fclose(profile); if (tox_is_data_encrypted(data)) { pass_ptrA password(mir_utf8encodeW(pass_ptrT(getTStringA("Password")))); if (password == NULL || mir_strlen(password) == 0) { CToxPasswordEditor passwordEditor(this); if (!passwordEditor.DoModal()) { mir_free(data); return false; } } uint8_t *encryptedData = (uint8_t*)mir_calloc(size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH); TOX_ERR_DECRYPTION coreDecryptError; if (!tox_pass_decrypt(data, size, (uint8_t*)(char*)password, mir_strlen(password), encryptedData, &coreDecryptError)) { ShowNotification(TranslateT("Unable to decrypt Tox profile"), MB_ICONERROR); debugLogA(__FUNCTION__": failed to decrypt tox profile (%d)", coreDecryptError); mir_free(data); return false; } mir_free(data); data = encryptedData; size -= TOX_PASS_ENCRYPTION_EXTRA_LENGTH; } if (data) { options->savedata_data = data; options->savedata_length = size; options->savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; return true; } return false; }
int __cdecl CMsnProto::SendMsg(HANDLE hContact, int flags, const char* pszSrc) { const char *errMsg = NULL; if (!msnLoggedIn) { errMsg = MSN_Translate("Protocol is offline"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, 999999, errMsg, this)); return 999999; } char tEmail[MSN_MAX_EMAIL_LEN]; if (MSN_IsMeByContact(hContact, tEmail)) { errMsg = MSN_Translate("You cannot send message to yourself"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, 999999, errMsg, this)); return 999999; } char *msg = (char*)pszSrc; if (msg == NULL) return 0; if (flags & PREF_UNICODE) { char* p = strchr(msg, '\0'); if (p != msg) { while (*(++p) == '\0') {} msg = mir_utf8encodeW((wchar_t*)p); } else msg = mir_strdup(msg); } else msg = (flags & PREF_UTF) ? mir_strdup(msg) : mir_utf8encode(msg); int rtlFlag = (flags & PREF_RTL) ? MSG_RTL : 0; int seq = 0; int netId = Lists_GetNetId(tEmail); switch (netId) { case NETID_MOB: if (strlen(msg) > 133) { errMsg = MSN_Translate("Message is too long: SMS page limited to 133 UTF8 chars"); seq = 999997; } else { errMsg = NULL; seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag); } ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); break; case NETID_YAHOO: if (strlen(msg) > 1202) { seq = 999996; errMsg = MSN_Translate("Message is too long: MSN messages are limited by 1202 UTF8 chars"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } else { seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } break; default: if (strlen(msg) > 1202) { seq = 999996; errMsg = MSN_Translate("Message is too long: MSN messages are limited by 1202 UTF8 chars"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } else { const char msgType = MyOptions.SlowSend ? 'A' : 'N'; bool isOffline; ThreadData* thread = MSN_StartSB(tEmail, isOffline); if (thread == NULL) { if (isOffline) { if (netId != NETID_LCS) { seq = msnNsThread->sendMessage('1', tEmail, netId, msg, rtlFlag | MSG_OFFLINE); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } else { seq = 999993; errMsg = MSN_Translate("Offline messaging is not allowed for LCS contacts"); ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, errMsg, this)); } } else seq = MsgQueue_Add(tEmail, msgType, msg, 0, 0, rtlFlag); } else { seq = thread->sendMessage(msgType, tEmail, netId, msg, rtlFlag); if (!MyOptions.SlowSend) ForkThread(&CMsnProto::MsnFakeAck, new TFakeAckParams(hContact, seq, NULL, this)); } } break; } mir_free(msg); return seq; }
char* CDropbox::PreparePath(const TCHAR *oldPath, char *newPath) { return PreparePath(ptrA(mir_utf8encodeW(oldPath)), newPath); }
static INT_PTR WriteContactSetting(WPARAM wParam, LPARAM lParam) { DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; DBCONTACTWRITESETTING tmp; struct DBContact dbc; DWORD ofsModuleName; struct DBContactSettings dbcs; PBYTE pBlob; int settingNameLen=0; int moduleNameLen=0; int settingDataLen=0; int bytesRequired,bytesRemaining; DWORD ofsContact,ofsSettingsGroup,ofsBlobPtr; if (dbcws == NULL || dbcws->szSetting==NULL || dbcws->szModule==NULL ) return 1; // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name settingNameLen=(int)strlen(dbcws->szSetting); moduleNameLen=(int)strlen(dbcws->szModule); if ( settingNameLen > 0xFE ) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); #endif return 1; } if ( moduleNameLen > 0xFE ) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); #endif return 1; } tmp = *dbcws; if (tmp.value.type == DBVT_WCHAR) { if (tmp.value.pszVal != NULL) { char* val = mir_utf8encodeW(tmp.value.pwszVal); if ( val == NULL ) return 1; tmp.value.pszVal = ( char* )_malloca( strlen( val )+1 ); strcpy( tmp.value.pszVal, val ); mir_free(val); tmp.value.type = DBVT_UTF8; } else return 1; } if(tmp.value.type!=DBVT_BYTE && tmp.value.type!=DBVT_WORD && tmp.value.type!=DBVT_DWORD && tmp.value.type!=DBVT_ASCIIZ && tmp.value.type!=DBVT_UTF8 && tmp.value.type!=DBVT_BLOB) return 1; if ((!tmp.szModule) || (!tmp.szSetting) || ((tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8 )&& tmp.value.pszVal == NULL) || (tmp.value.type == DBVT_BLOB && tmp.value.pbVal == NULL) ) return 1; // the db can not tolerate strings/blobs longer than 0xFFFF since the format writes 2 lengths switch( tmp.value.type ) { case DBVT_ASCIIZ: case DBVT_BLOB: case DBVT_UTF8: { size_t len = ( tmp.value.type != DBVT_BLOB ) ? (int)strlen(tmp.value.pszVal) : tmp.value.cpbVal; if ( len >= 0xFFFF ) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n"); #endif return 1; } } } EnterCriticalSection(&csDbAccess); { char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen); if ( tmp.value.type != DBVT_BLOB ) { DBVARIANT* pCachedValue = GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, 1); if ( pCachedValue != NULL ) { BOOL bIsIdentical = FALSE; if ( pCachedValue->type == tmp.value.type ) { switch(tmp.value.type) { case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == tmp.value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == tmp.value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == tmp.value.dVal; break; case DBVT_UTF8: case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, tmp.value.pszVal ) == 0; break; } if ( bIsIdentical ) { LeaveCriticalSection(&csDbAccess); return 0; } } SetCachedVariant(&tmp.value, pCachedValue); } if ( szCachedSettingName[-1] != 0 ) { LeaveCriticalSection(&csDbAccess); NotifyEventHooks(hSettingChangeEvent,wParam,(LPARAM)&tmp); return 0; } } else GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, -1); } ofsModuleName=GetModuleNameOfs(tmp.szModule); if(wParam==0) ofsContact=dbHeader.ofsUser; else ofsContact=wParam; dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); if(dbc.signature!=DBCONTACT_SIGNATURE) { LeaveCriticalSection(&csDbAccess); return 1; } log0("write setting"); //make sure the module group exists ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsModuleName); if(ofsSettingsGroup==0) { //module group didn't exist - make it if(tmp.value.type&DBVTF_VARIABLELENGTH) { if(tmp.value.type==DBVT_ASCIIZ || tmp.value.type==DBVT_UTF8) bytesRequired = (int)strlen(tmp.value.pszVal)+2; else if(tmp.value.type==DBVT_BLOB) bytesRequired=tmp.value.cpbVal+2; } else bytesRequired=tmp.value.type; bytesRequired+=2+settingNameLen; bytesRequired+=(DB_SETTINGS_RESIZE_GRANULARITY-(bytesRequired%DB_SETTINGS_RESIZE_GRANULARITY))%DB_SETTINGS_RESIZE_GRANULARITY; ofsSettingsGroup=CreateNewSpace(bytesRequired+offsetof(struct DBContactSettings,blob)); dbcs.signature=DBCONTACTSETTINGS_SIGNATURE; dbcs.ofsNext=dbc.ofsFirstSettings; dbcs.ofsModuleName=ofsModuleName; dbcs.cbBlob=bytesRequired; dbcs.blob[0]=0; dbc.ofsFirstSettings=ofsSettingsGroup; DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); DBWrite(ofsSettingsGroup,&dbcs,sizeof(struct DBContactSettings)); ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob); pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); } else {
void Send(WCHAR *ws) { char *s = mir_utf8encodeW(ws); m_socket->Send(s); mir_free(s); }