Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
0
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; 
}
Пример #6
0
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);
}
Пример #7
0
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;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
0
// 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;
}
Пример #11
0
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;
}
Пример #12
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
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;
}
Пример #16
0
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);
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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");
		}

	}

}
Пример #20
0
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;
}
Пример #21
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;
}
Пример #22
0
void NLog(wchar_t *msg) 
{
	char* a = mir_utf8encodeW(msg);
	CallService(MS_NETLIB_LOG, (WPARAM)hNetlibUser, (LPARAM)a);
	mir_free(a);
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
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;
}
Пример #26
0
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;
}
Пример #27
0
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;
}
Пример #28
0
char* CDropbox::PreparePath(const TCHAR *oldPath, char *newPath)
{
	return PreparePath(ptrA(mir_utf8encodeW(oldPath)), newPath);
}
Пример #29
0
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 {
Пример #30
0
	void Send(WCHAR *ws)
	{
		char *s = mir_utf8encodeW(ws);
		m_socket->Send(s);
		mir_free(s);
	}