From 306f3cd382fe210562f14f90522c33073c285344 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 17 Feb 2020 20:13:53 +0300 Subject: Jabber: full implementation of XEP-0231 --- protocols/JabberG/src/jabber_file.cpp | 18 ++--- protocols/JabberG/src/jabber_ft.cpp | 138 +++++++++++++++++++++++++++++--- protocols/JabberG/src/jabber_iq.cpp | 3 + protocols/JabberG/src/jabber_iqid.cpp | 22 ++--- protocols/JabberG/src/jabber_proto.cpp | 6 +- protocols/JabberG/src/jabber_proto.h | 3 +- protocols/JabberG/src/jabber_search.cpp | 6 +- protocols/JabberG/src/jabber_thread.cpp | 4 +- protocols/JabberG/src/jabber_util.cpp | 4 +- 9 files changed, 160 insertions(+), 44 deletions(-) (limited to 'protocols') 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 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, 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 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); } } } -- cgit v1.2.3