diff options
| author | George Hazan <ghazan@miranda.im> | 2020-02-17 20:13:53 +0300 | 
|---|---|---|
| committer | George Hazan <ghazan@miranda.im> | 2020-02-17 20:13:53 +0300 | 
| commit | 306f3cd382fe210562f14f90522c33073c285344 (patch) | |
| tree | 870af4804194ce3d170ff0599d1c01891f3c22e1 /protocols | |
| parent | 748f064db28f9801f3851dd2a6e5d74b94dbdc38 (diff) | |
Jabber: full implementation of XEP-0231
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/JabberG/src/jabber_file.cpp | 18 | ||||
| -rw-r--r-- | protocols/JabberG/src/jabber_ft.cpp | 138 | ||||
| -rw-r--r-- | protocols/JabberG/src/jabber_iq.cpp | 3 | ||||
| -rwxr-xr-x | protocols/JabberG/src/jabber_iqid.cpp | 22 | ||||
| -rwxr-xr-x | protocols/JabberG/src/jabber_proto.cpp | 6 | ||||
| -rwxr-xr-x | protocols/JabberG/src/jabber_proto.h | 3 | ||||
| -rw-r--r-- | protocols/JabberG/src/jabber_search.cpp | 6 | ||||
| -rwxr-xr-x | protocols/JabberG/src/jabber_thread.cpp | 4 | ||||
| -rwxr-xr-x | protocols/JabberG/src/jabber_util.cpp | 4 | 
9 files changed, 160 insertions, 44 deletions
| diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp index ce3907c04d..2e9b30f90f 100644 --- a/protocols/JabberG/src/jabber_file.cpp +++ b/protocols/JabberG/src/jabber_file.cpp @@ -42,7 +42,7 @@ void __cdecl CJabberProto::FileReceiveThread(filetransfer *ft)  	info.s = Netlib_OpenConnection(m_hNetlibUser, &nloc);
  	if (info.s == nullptr) {
  		debugLogA("Connection failed (%d), thread ended", WSAGetLastError());
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft);
  	}
  	else {
  		ft->s = info.s;
 @@ -107,7 +107,7 @@ int CJabberProto::FileReceiveParse(filetransfer *ft, char* buffer, int datalen)  					ft->state = FT_INITIALIZING;
  					ft->std.currentFileSize = -1;
  					debugLogA("Change to FT_INITIALIZING");
 -					ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0);
 +					ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft);
  				}
  			}
  			else {	// FT_INITIALIZING
 @@ -247,7 +247,7 @@ void __cdecl CJabberProto::FileServerThread(filetransfer *ft)  	info.s = (HNETLIBCONN)Netlib_BindPort(m_hNetlibUser, &nlb);
  	if (info.s == nullptr) {
  		debugLogA("Cannot allocate port to bind for file server thread, thread ended.");
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft);
  		delete ft;
  		return;
  	}
 @@ -304,7 +304,7 @@ void __cdecl CJabberProto::FileServerThread(filetransfer *ft)  				WaitForSingleObject(hEvent, INFINITE);
  			}
  			debugLogA("File sent, advancing to the next file...");
 -			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
 +			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft);
  		}
  		CloseHandle(hEvent);
  		ft->hFileEvent = nullptr;
 @@ -319,14 +319,14 @@ void __cdecl CJabberProto::FileServerThread(filetransfer *ft)  	switch (ft->state) {
  	case FT_DONE:
  		debugLogA("Finish successfully");
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
  		break;
  	case FT_DENIED:
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft);
  		break;
  	default: // FT_ERROR:
  		debugLogA("Finish with errors");
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft);
  		break;
  	}
 @@ -449,7 +449,7 @@ filetransfer::~filetransfer()  	ppro->debugLogA("Destroying file transfer session %08p", this);
  	if (!bCompleted)
 -		ppro->ProtoBroadcastAck(std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, this, 0);
 +		ppro->ProtoBroadcastAck(std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, this);
  	close();
 @@ -485,7 +485,7 @@ void filetransfer::complete()  	close();
  	bCompleted = true;
 -	ppro->ProtoBroadcastAck(std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, this, 0);
 +	ppro->ProtoBroadcastAck(std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, this);
  }
  int filetransfer::create()
 diff --git a/protocols/JabberG/src/jabber_ft.cpp b/protocols/JabberG/src/jabber_ft.cpp index d0b5b41bfe..c28fc1e7f7 100644 --- a/protocols/JabberG/src/jabber_ft.cpp +++ b/protocols/JabberG/src/jabber_ft.cpp @@ -44,7 +44,7 @@ void CJabberProto::FtCancel(filetransfer *ft)  		if (item->ft == ft) {
  			debugLogA("Canceling file receiving session while in si negotiation");
  			ListRemoveByIndex(i);
 -			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
 +			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft);
  			delete ft;
  			return;
  		}
 @@ -75,12 +75,21 @@ void CJabberProto::FtCancel(filetransfer *ft)  ///////////////// File sending using stream initiation /////////////////////////
 +static void __cdecl FakeAckThread(void *param)
 +{
 +	Sleep(100);
 +
 +	auto *ft = (filetransfer *)param;
 +	ft->complete();
 +	delete ft;
 +}
 +
  void CJabberProto::FtInitiate(const char* jid, filetransfer *ft)
  {
  	char *rs = ListGetBestClientResourceNamePtr(jid);
  	if (ft == nullptr || !m_bJabberOnline || rs == nullptr) {
  		if (ft) {
 -			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0);
 +			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft);
  			delete ft;
  		}
  		return;
 @@ -92,9 +101,8 @@ void CJabberProto::FtInitiate(const char* jid, filetransfer *ft)  	// if we enabled XEP-0231, try to inline a picture
  	if (m_bInlinePictures && ProtoGetAvatarFileFormat(ft->std.szCurrentFile.w)) {
 -		if (FtTryInlineFile(ft->std.szCurrentFile.w)) {
 -			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
 -			delete ft;
 +		if (FtTryInlineFile(ft->std.hContact, ft->std.szCurrentFile.w)) {
 +			mir_forkthread(FakeAckThread, ft);
  			return;
  		}
  	}
 @@ -212,7 +220,7 @@ void CJabberProto::OnFtSiResult(const TiXmlElement *iqNode, CJabberIqInfo *pInfo  	}
  	else {
  		debugLogA("File transfer stream initiation request denied or failed");
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ? ACKRESULT_DENIED : ACKRESULT_FAILED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ? ACKRESULT_DENIED : ACKRESULT_FAILED, ft);
  		delete ft;
  	}
  }
 @@ -311,18 +319,18 @@ void CJabberProto::FtSendFinal(BOOL success, filetransfer *ft)  {
  	if (!success) {
  		debugLogA("File transfer complete with error");
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ft->state == FT_DENIED ? ACKRESULT_DENIED : ACKRESULT_FAILED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ft->state == FT_DENIED ? ACKRESULT_DENIED : ACKRESULT_FAILED, ft);
  	}
  	else {
  		if (ft->std.currentFileNumber < ft->std.totalFiles - 1) {
  			ft->std.currentFileNumber++;
  			replaceStrW(ft->std.szCurrentFile.w, ft->std.pszFiles.w[ft->std.currentFileNumber]);
 -			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
 +			ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft);
  			FtInitiate(ft->jid, ft);
  			return;
  		}
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
  	}
  	delete ft;
 @@ -581,7 +589,7 @@ void CJabberProto::OnHttpSlotAllocated(const TiXmlElement *iqNode, CJabberIqInfo  	if (pInfo->GetIqType() != JABBER_IQ_TYPE_RESULT) {
  		debugLogA("HTTP upload aborted");
  LBL_Fail:
 -		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ? ACKRESULT_DENIED : ACKRESULT_FAILED, ft, 0);
 +		ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, pInfo->GetIqType() == JABBER_IQ_TYPE_ERROR ? ACKRESULT_DENIED : ACKRESULT_FAILED, ft);
  		delete ft;
  		return;
  	}
 @@ -664,7 +672,7 @@ LBL_Fail:  					ProtoChainRecvMsg(ft->std.hContact, &recv);
  				}
 -				ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0);
 +				ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
  				delete ft;
  				return;
  			}
 @@ -677,7 +685,111 @@ LBL_Fail:  /////////////////////////////////////////////////////////////////////////////////////////
 -bool CJabberProto::FtTryInlineFile(const wchar_t *pwszFileName)
 +bool CJabberProto::FtTryInlineFile(MCONTACT hContact, const wchar_t *pwszFileName)
  {
 -	return false;
 +	int fileFormat = ProtoGetAvatarFormat(pwszFileName);
 +	if (fileFormat == PA_FORMAT_UNKNOWN)
 +		return false;
 +
 +	char szClientJid[JABBER_MAX_JID_LEN];
 +	if (!m_bJabberOnline || !GetClientJID(hContact, szClientJid, _countof(szClientJid)))
 +		return false;
 +
 +	int fileId = _wopen(pwszFileName, _O_BINARY | _O_RDONLY);
 +	if (fileId < 0) {
 +		debugLogW(L"File %s cannot be opened for inlining", pwszFileName);
 +		return false;
 +	}
 +
 +	SHA_CTX ctx;
 +	SHA1_Init(&ctx);
 +	while (!_eof(fileId)) {
 +		char buf[1024];
 +		int nBytes = _read(fileId, buf, _countof(buf));
 +		SHA1_Update(&ctx, buf, nBytes);
 +	}
 +	_close(fileId);
 +
 +	uint8_t hash[MIR_SHA1_HASH_SIZE];
 +	SHA1_Final(hash, &ctx);
 +	char szHash[MIR_SHA1_HASH_SIZE*2 + 1];
 +	bin2hex(hash, sizeof(hash), szHash);
 +
 +	VARSW wszTempPath(L"%miranda_userdata%\\JabberTmp");
 +	CreateDirectoryTreeW(wszTempPath);
 +
 +	CMStringW wszFileName(FORMAT, L"%s\\%S%s", wszTempPath.get(), szHash, ProtoGetAvatarExtension(fileFormat));
 +	if (_waccess(wszFileName, 0))
 +		if (CopyFileW(pwszFileName, wszFileName, FALSE)) {
 +			DWORD dwError = GetLastError();
 +			debugLogW(L"File <%s> cannot be copied to <%s>: error %d", pwszFileName, wszFileName.c_str(), dwError);
 +			return false;
 +		}
 +
 +	XmlNode m("message");
 +
 +	if (ListGetItemPtr(LIST_CHATROOM, szClientJid) && strchr(szClientJid, '/') == nullptr)
 +		XmlAddAttr(m, "type", "groupchat");
 +	else
 +		XmlAddAttr(m, "type", "chat");
 +	XmlAddAttr(m, "to", szClientJid);
 +	XmlAddAttrID(m, SerialNext());
 +
 +	auto *nHtml = m << XCHILDNS("html", JABBER_FEAT_XHTML);
 +	auto *nBody = nHtml << XCHILDNS("body", "http://www.w3.org/1999/xhtml");
 +	auto *nPara = nBody << XCHILD("p");
 +	nPara << XCHILD("img") << XATTR("src", CMStringA(FORMAT, "cid:sha1+%s@bob.xmpp.org", szHash));
 +
 +	m << XCHILDNS("request", JABBER_FEAT_MESSAGE_RECEIPTS);
 +	m << XCHILDNS("markable", JABBER_FEAT_CHAT_MARKERS);
 +	m_ThreadInfo->send(m);
 +
 +	return true;
 +}
 +
 +bool CJabberProto::FtHandleCidRequest(const TiXmlElement*, CJabberIqInfo *pInfo)
 +{
 +	auto *pChild = pInfo->GetChildNode();
 +	if (pChild == nullptr)
 +		return true;
 +
 +	const char *cid = XmlGetAttr(pChild, "cid");
 +	if (cid == nullptr) {
 +	LBL_Error:
 +		XmlNodeIq iq("error", pInfo);
 +		TiXmlElement *error = iq << XCHILD("error") << XATTRI("code", 400) << XATTR("type", "cancel");
 +		error << XCHILDNS("bad-request", "urn:ietf:params:xml:ns:xmpp-stanzas");
 +		m_ThreadInfo->send(iq);
 +		return true;
 +	}
 +
 +	if (memcmp(cid, "sha1+", 5))
 +		goto LBL_Error;
 +
 +	CMStringA szCid(cid);
 +	szCid.Delete(0, 5); szCid.Truncate(40);
 +	VARSW wszTempPath(L"%miranda_userdata%\\JabberTmp");
 +	CMStringW wszFileMask(FORMAT, L"%s\\%S.*", wszTempPath.get(), szCid.c_str());
 +	WIN32_FIND_DATAW data;
 +	HANDLE hFind = FindFirstFileW(wszFileMask, &data);
 +	if (hFind == nullptr)
 +		goto LBL_Error;
 +	
 +	FindClose(hFind);
 +
 +	int fileFormat = ProtoGetAvatarFormat(data.cFileName);
 +	wszFileMask.Format(L"%s\\%s", wszTempPath.get(), data.cFileName);
 +	int fileId = _wopen(wszFileMask, _O_BINARY | _O_RDONLY);
 +	if (fileId < 0)
 +		goto LBL_Error;
 +
 +	mir_ptr<BYTE> buf((BYTE *)mir_alloc(data.nFileSizeLow));
 +	_read(fileId, buf, data.nFileSizeLow);
 +	_close(fileId);
 +
 +	XmlNodeIq iq("result", pInfo);
 +	auto *pData = iq << XCHILDNS("data", JABBER_FEAT_BITS) << XATTR("max-age", "2565000") << XATTR("type", ProtoGetAvatarMimeType(fileFormat)) << XATTR("cid", cid);
 +	pData->SetText(ptrA(mir_base64_encode(buf, data.nFileSizeLow)).get());
 +	m_ThreadInfo->send(iq);
 +	return true;
  }
 diff --git a/protocols/JabberG/src/jabber_iq.cpp b/protocols/JabberG/src/jabber_iq.cpp index ab6d07bec2..45fb2227c8 100644 --- a/protocols/JabberG/src/jabber_iq.cpp +++ b/protocols/JabberG/src/jabber_iq.cpp @@ -128,6 +128,9 @@ void CJabberIqManager::FillPermanentHandlers()  	// http auth (XEP-0070)
  	AddPermanentHandler(&CJabberProto::OnIqHttpAuth, JABBER_IQ_TYPE_GET, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_ID_STR | JABBER_IQ_PARSE_CHILD_TAG_NODE, JABBER_FEAT_HTTP_AUTH, FALSE, "confirm");
 +
 +	// XEP-0231 support
 +	AddPermanentHandler(&CJabberProto::FtHandleCidRequest, JABBER_IQ_TYPE_GET, JABBER_IQ_PARSE_FROM | JABBER_IQ_PARSE_TO | JABBER_IQ_PARSE_ID_STR | JABBER_IQ_PARSE_CHILD_TAG_NODE, JABBER_FEAT_BITS, FALSE, "data");
  }
  void __cdecl CJabberProto::ExpirerThread(void* pParam)
 diff --git a/protocols/JabberG/src/jabber_iqid.cpp b/protocols/JabberG/src/jabber_iqid.cpp index 64ca5d58c1..0a40a61b8b 100755 --- a/protocols/JabberG/src/jabber_iqid.cpp +++ b/protocols/JabberG/src/jabber_iqid.cpp @@ -658,12 +658,12 @@ void CJabberProto::OnIqResultGetVcard(const TiXmlElement *iqNode, CJabberIqInfo*  				psr.email.a = (char*)XmlGetChildText(vCardNode, "EMAIL");
  				psr.id.a = NEWSTR_ALLOCA(jid);
  				ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)id, (LPARAM)&psr);
 -				ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +				ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  			}
  			else if (!mir_strcmp(type, "error"))
 -				ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +				ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  		}
 -		else ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +		else ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  		return;
  	}
 @@ -1106,7 +1106,7 @@ void CJabberProto::OnIqResultGetVcard(const TiXmlElement *iqNode, CJabberIqInfo*  	if (!hasPhoto) {
  		debugLogA("Has no avatar");
  		if (!delSetting(hContact, "AvatarHash"))
 -			ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, nullptr, 0);
 +			ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, nullptr);
  	}
  	if (id == m_ThreadInfo->resolveID) {
 @@ -1174,10 +1174,10 @@ void CJabberProto::OnIqResultSetSearch(const TiXmlElement *iqNode, CJabberIqInfo  			}
  		}
 -		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  	}
  	else if (!mir_strcmp(type, "error"))
 -		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  }
  void CJabberProto::OnIqResultExtSearch(const TiXmlElement *iqNode, CJabberIqInfo*)
 @@ -1235,10 +1235,10 @@ void CJabberProto::OnIqResultExtSearch(const TiXmlElement *iqNode, CJabberIqInfo  			replaceStrW(psr.email.w, 0);
  		}
 -		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  	}
  	else if (!mir_strcmp(type, "error"))
 -		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0);
 +		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);
  }
  void CJabberProto::OnIqResultSetPassword(const TiXmlElement *iqNode, CJabberIqInfo*)
 @@ -1280,7 +1280,7 @@ void CJabberProto::OnIqResultGetVCardAvatar(const TiXmlElement *iqNode, CJabberI  	if (vCard->NoChildren()) {
  		if (!delSetting(hContact, "AvatarHash"))
 -			ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, nullptr, 0);
 +			ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, nullptr);
  		return;
  	}
 @@ -1373,10 +1373,10 @@ void CJabberProto::OnIqResultGotAvatar(MCONTACT hContact, const char *pszText, c  		char buffer[41];
  		setString(hContact, "AvatarHash", bin2hex(digest, sizeof(digest), buffer));
 -		ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai), 0);
 +		ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai));
  		debugLogW(L"Broadcast new avatar: %s", ai.filename);
  	}
 -	else ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai), 0);
 +	else ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai));
  }
  /////////////////////////////////////////////////////////////////////////////////////////
 diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index 75f1e735a1..9129f46ba8 100755 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -691,7 +691,7 @@ void __cdecl CJabberProto::BasicSearchThread(JABBER_SEARCH_BASIC *jsb)  	psr.id.w = jsb->jid;
  	ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)jsb->hSearch, (LPARAM)&psr);
 -	ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)jsb->hSearch, 0);
 +	ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)jsb->hSearch);
  	mir_free(jsb);
  }
 @@ -986,7 +986,7 @@ int CJabberProto::SendMsg(MCONTACT hContact, int unused_unknown, const char *psz  			m << XCHILD("body", pszSrc);
  		else {
  			m << XCHILD("body", "[This message is encrypted.]");
 -			m << XCHILD("x", pszSrc) << XATTR("xmlns", "jabber:x:encrypted");
 +			m << XCHILDNS("x", "jabber:x:encrypted");
  		}
  	}
 @@ -1159,7 +1159,7 @@ void __cdecl CJabberProto::GetAwayMsgThread(void *param)  		}
  	}
 -	ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0);
 +	ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1);
  }
  HANDLE CJabberProto::GetAwayMsg(MCONTACT hContact)
 diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 4457f77573..b7bd700ffb 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -502,7 +502,8 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface  	void       FtAcceptIbbRequest(filetransfer *ft);
  	bool       FtHandleBytestreamRequest(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
  	bool       FtHandleIbbRequest(const TiXmlElement *iqNode, bool bOpen);
 -	bool       FtTryInlineFile(const wchar_t *pwszFileName);
 +	bool       FtTryInlineFile(MCONTACT hContact, const wchar_t *pwszFileName);
 +	bool       FtHandleCidRequest(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
  	//---- jabber_groupchat.c ------------------------------------------------------------
 diff --git a/protocols/JabberG/src/jabber_search.cpp b/protocols/JabberG/src/jabber_search.cpp index 8df2fe88dc..59c410aa52 100644 --- a/protocols/JabberG/src/jabber_search.cpp +++ b/protocols/JabberG/src/jabber_search.cpp @@ -303,7 +303,7 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI  	LIST<UNIQUE_MAP> SearchResults(2);  	if (((id = JabberGetPacketID(iqNode)) == -1) || ((type = XmlGetAttr(iqNode, "type")) == nullptr)) { -		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); +		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);  		return;  	} @@ -371,7 +371,7 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI  			description = errorNode->GetText();  		} -		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); +		ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);  		char buff[255];  		mir_snprintf(buff, TranslateU("Error %s %s\r\nTry to specify more detailed"), code, description); @@ -388,7 +388,7 @@ void CJabberProto::OnIqResultAdvancedSearch(const TiXmlElement *iqNode, CJabberI  		delete ((UNIQUE_MAP*)it);  	//send success to finish searching -	ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); +	ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id);  }  static BOOL CALLBACK DeleteChildWindowsProc(HWND hwnd, LPARAM) diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 87972f5cc0..aaa9e1b5af 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1197,7 +1197,7 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info)  		if (nPacketId == -1)
  			nPacketId = JabberGetPacketID(node);
  		if (nPacketId != -1)
 -			ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)nPacketId, 0);
 +			ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)nPacketId);
  	}
  	if (auto *n = XmlGetChildByTag(node, "displayed", "xmlns", JABBER_FEAT_CHAT_MARKERS))
 @@ -1634,7 +1634,7 @@ void CJabberProto::OnProcessPresence(const TiXmlElement *node, ThreadData *info)  			if (!bHasAvatar && bRemovedAvatar) {
  				debugLogA("Has no avatar");
  				if (!delSetting(hContact, "AvatarHash"))
 -					ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, nullptr, 0);
 +					ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, nullptr);
  			}
  		}
  		return;
 diff --git a/protocols/JabberG/src/jabber_util.cpp b/protocols/JabberG/src/jabber_util.cpp index 1b0509decc..770df68ddd 100755 --- a/protocols/JabberG/src/jabber_util.cpp +++ b/protocols/JabberG/src/jabber_util.cpp @@ -931,10 +931,10 @@ void __cdecl CJabberProto::LoadHttpAvatars(void* param)  							fwrite(res->pData, res->dataLength, 1, out);
  							fclose(out);
  							setString(ai.hContact, "AvatarHash", buffer);
 -							ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai, 0);
 +							ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
  							debugLogW(L"Broadcast new avatar: %s", ai.filename);
  						}
 -						else ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai, 0);
 +						else ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai);
  					}
  				}
  			}
 | 
