From 3b55a62fdcb1f8222de3c2c8fbed530792c419a0 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 12 Oct 2012 14:53:57 +0000 Subject: GTalkExt, ICQ, IRC, Jabber: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1890 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/IcqOscarJ/src/directpackets.cpp | 293 ++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 protocols/IcqOscarJ/src/directpackets.cpp (limited to 'protocols/IcqOscarJ/src/directpackets.cpp') diff --git a/protocols/IcqOscarJ/src/directpackets.cpp b/protocols/IcqOscarJ/src/directpackets.cpp new file mode 100644 index 0000000000..594f005675 --- /dev/null +++ b/protocols/IcqOscarJ/src/directpackets.cpp @@ -0,0 +1,293 @@ +// ---------------------------------------------------------------------------80 +// ICQ plugin for Miranda Instant Messenger +// ________________________________________ +// +// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede +// Copyright © 2001-2002 Jon Keating, Richard Hughes +// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater +// Copyright © 2004-2010 Joe Kucera +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// ----------------------------------------------------------------------------- +// DESCRIPTION: +// +// Describe me here please... +// +// ----------------------------------------------------------------------------- +#include "icqoscar.h" + +void EncryptDirectPacket(directconnect* dc, icq_packet* p); + +void packEmptyMsg(icq_packet *packet); + +static void packDirectMsgHeader(icq_packet* packet, WORD wDataLen, WORD wCommand, DWORD dwCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wX1, WORD wX2) +{ + directPacketInit(packet, 29 + wDataLen); + packByte(packet, 2); /* channel */ + packLEDWord(packet, 0); /* space for crypto */ + packLEWord(packet, wCommand); + packLEWord(packet, 14); /* unknown */ + packLEWord(packet, (WORD)dwCookie); + packLEDWord(packet, 0); /* unknown */ + packLEDWord(packet, 0); /* unknown */ + packLEDWord(packet, 0); /* unknown */ + packByte(packet, bMsgType); + packByte(packet, bMsgFlags); + packLEWord(packet, wX1); /* unknown. Is 1 for getawaymsg, 0 otherwise */ + packLEWord(packet, wX2); // this is probably priority +} + + +void CIcqProto::icq_sendDirectMsgAck(directconnect* dc, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, char* szCap) +{ + icq_packet packet; + + packDirectMsgHeader(&packet, (WORD)(bMsgType==MTYPE_PLAIN ? (szCap ? 53 : 11) : 3), DIRECT_ACK, wCookie, bMsgType, bMsgFlags, 0, 0); + packEmptyMsg(&packet); /* empty message */ + + if (bMsgType == MTYPE_PLAIN) + { + packMsgColorInfo(&packet); + + if (szCap) + { + packLEDWord(&packet, 0x26); /* CLSID length */ + packBuffer(&packet, (LPBYTE)szCap, 0x26); /* GUID */ + } + } + EncryptDirectPacket(dc, &packet); + sendDirectPacket(dc, &packet); + + NetLog_Direct("Sent acknowledgement thru direct connection"); +} + + +DWORD CIcqProto::icq_sendGetAwayMsgDirect(HANDLE hContact, int type) +{ + icq_packet packet; + DWORD dwCookie; + cookie_message_data *pCookieData; + + if (getSettingWord(hContact, "Version", 0) == 9) + return 0; // v9 DC protocol does not support this message + + pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type); + dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); + + packDirectMsgHeader(&packet, 3, DIRECT_MESSAGE, dwCookie, (BYTE)type, 3, 1, 0); + packEmptyMsg(&packet); // message + + return (SendDirectMessage(hContact, &packet)) ? dwCookie : 0; +} + + +void CIcqProto::icq_sendAwayMsgReplyDirect(directconnect* dc, WORD wCookie, BYTE msgType, const char** szMsg) +{ + icq_packet packet; + + if (validateStatusMessageRequest(dc->hContact, msgType)) + { + NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dc->dwRemoteUin); + + icq_lock l(m_modeMsgsMutex); + + if (szMsg && *szMsg) + { + // prepare Ansi message - only Ansi supported + WORD wMsgLen = strlennull(*szMsg) + 1; + char *szAnsiMsg = (char*)_alloca(wMsgLen); + + utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen); + wMsgLen = strlennull(szAnsiMsg); + packDirectMsgHeader(&packet, (WORD)(3 + wMsgLen), DIRECT_ACK, wCookie, msgType, 3, 0, 0); + packLEWord(&packet, (WORD)(wMsgLen + 1)); + packBuffer(&packet, (LPBYTE)szAnsiMsg, (WORD)(wMsgLen + 1)); + EncryptDirectPacket(dc, &packet); + + sendDirectPacket(dc, &packet); + } + } +} + + +void CIcqProto::icq_sendFileAcceptDirect(HANDLE hContact, filetransfer* ft) +{ + // v7 packet + icq_packet packet; + + packDirectMsgHeader(&packet, 18, DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0); + packLEWord(&packet, 1); // description + packByte(&packet, 0); + packWord(&packet, wListenPort); + packLEWord(&packet, 0); + packLEWord(&packet, 1); // filename + packByte(&packet, 0); // TODO: really send filename + packLEDWord(&packet, ft->dwTotalSize); // file size + packLEDWord(&packet, wListenPort); // FIXME: ideally we want to open a new port for this + + SendDirectMessage(hContact, &packet); + + NetLog_Direct("Sent file accept direct, port %u", wListenPort); +} + + +void CIcqProto::icq_sendFileDenyDirect(HANDLE hContact, filetransfer *ft, const char *szReason) +{ + // v7 packet + icq_packet packet; + char *szReasonAnsi = NULL; + int cbReasonAnsi = 0; + + if (!utf8_decode(szReason, &szReasonAnsi)) + szReasonAnsi = NULL; + else + cbReasonAnsi = strlennull(szReasonAnsi); + + packDirectMsgHeader(&packet, (WORD)(18 + cbReasonAnsi), DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 1, 0); + packLEWord(&packet, (WORD)(1 + cbReasonAnsi)); // description + if (szReasonAnsi) packBuffer(&packet, (LPBYTE)szReasonAnsi, (WORD)cbReasonAnsi); + packByte(&packet, 0); + packWord(&packet, 0); + packLEWord(&packet, 0); + packLEWord(&packet, 1); // filename + packByte(&packet, 0); // TODO: really send filename + packLEDWord(&packet, 0); // file size + packLEDWord(&packet, 0); + + SAFE_FREE(&szReasonAnsi); + + SendDirectMessage(hContact, &packet); + + NetLog_Direct("Sent file deny direct."); +} + + +int CIcqProto::icq_sendFileSendDirectv7(filetransfer *ft, const char *pszFiles) +{ + icq_packet packet; + char *szFilesAnsi = NULL; + WORD wDescrLen = strlennull(ft->szDescription), wFilesLen = 0; + + if (!utf8_decode(pszFiles, &szFilesAnsi)) + szFilesAnsi = NULL; + else + wFilesLen = strlennull(szFilesAnsi); + + packDirectMsgHeader(&packet, (WORD)(18 + wDescrLen + wFilesLen), DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0); + packLEWord(&packet, (WORD)(wDescrLen + 1)); + packBuffer(&packet, (LPBYTE)ft->szDescription, (WORD)(wDescrLen + 1)); + packLEDWord(&packet, 0); // listen port + packLEWord(&packet, (WORD)(wFilesLen + 1)); + packBuffer(&packet, (LPBYTE)szFilesAnsi, (WORD)(wFilesLen + 1)); + packLEDWord(&packet, ft->dwTotalSize); + packLEDWord(&packet, 0); // listen port (again) + + SAFE_FREE(&szFilesAnsi); + + NetLog_Direct("Sending v%u file transfer request direct", 7); + + return SendDirectMessage(ft->hContact, &packet); +} + + +int CIcqProto::icq_sendFileSendDirectv8(filetransfer *ft, const char *pszFiles) +{ + icq_packet packet; + char *szFilesAnsi = NULL; + WORD wDescrLen = strlennull(ft->szDescription), wFilesLen = 0; + + if (!utf8_decode(pszFiles, &szFilesAnsi)) + szFilesAnsi = NULL; + else + wFilesLen = strlennull(szFilesAnsi); + + packDirectMsgHeader(&packet, (WORD)(0x2E + 22 + wDescrLen + wFilesLen + 1), DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_PLUGIN, 0, 0, 0); + packEmptyMsg(&packet); // message + packPluginTypeId(&packet, MTYPE_FILEREQ); + + packLEDWord(&packet, (WORD)(18 + wDescrLen + wFilesLen + 1)); // Remaining length + packLEDWord(&packet, wDescrLen); // Description + packBuffer(&packet, (LPBYTE)ft->szDescription, wDescrLen); + packWord(&packet, 0x8c82); // Unknown (port?), seen 0x80F6 + packWord(&packet, 0x0222); // Unknown, seen 0x2e01 + packLEWord(&packet, (WORD)(wFilesLen + 1)); + packBuffer(&packet, (LPBYTE)szFilesAnsi, (WORD)(wFilesLen + 1)); + packLEDWord(&packet, ft->dwTotalSize); + packLEDWord(&packet, 0x0008c82); // Unknown, (seen 0xf680 ~33000) + + SAFE_FREE(&szFilesAnsi); + + NetLog_Direct("Sending v%u file transfer request direct", 8); + + return SendDirectMessage(ft->hContact, &packet); +} + + +DWORD CIcqProto::icq_SendDirectMessage(HANDLE hContact, const char *szMessage, int nBodyLength, WORD wPriority, cookie_message_data *pCookieData, char *szCap) +{ + icq_packet packet; + DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); + + // Pack the standard header + packDirectMsgHeader(&packet, (WORD)(nBodyLength + (szCap ? 53:11)), DIRECT_MESSAGE, dwCookie, (BYTE)pCookieData->bMessageType, 0, 0, 0); + + packLEWord(&packet, (WORD)(nBodyLength+1)); // Length of message + packBuffer(&packet, (LPBYTE)szMessage, (WORD)(nBodyLength+1)); // Message + packMsgColorInfo(&packet); + if (szCap) + { + packLEDWord(&packet, 0x00000026); // length of GUID + packBuffer(&packet, (LPBYTE)szCap, 0x26); // UTF-8 GUID + } + + if (SendDirectMessage(hContact, &packet)) + return dwCookie; // Success + + FreeCookie(dwCookie); // release cookie + return 0; // Failure +} + +void CIcqProto::icq_sendXtrazRequestDirect(HANDLE hContact, DWORD dwCookie, char* szBody, int nBodyLen, WORD wType) +{ + icq_packet packet; + + packDirectMsgHeader(&packet, (WORD)(11 + getPluginTypeIdLen(wType) + nBodyLen), DIRECT_MESSAGE, dwCookie, MTYPE_PLUGIN, 0, 0, 1); + packEmptyMsg(&packet); // message (unused) + packPluginTypeId(&packet, wType); + + packLEDWord(&packet, nBodyLen + 4); + packLEDWord(&packet, nBodyLen); + packBuffer(&packet, (LPBYTE)szBody, (WORD)nBodyLen); + + SendDirectMessage(hContact, &packet); +} + +void CIcqProto::icq_sendXtrazResponseDirect(HANDLE hContact, WORD wCookie, char* szBody, int nBodyLen, WORD wType) +{ + icq_packet packet; + + packDirectMsgHeader(&packet, (WORD)(getPluginTypeIdLen(wType) + 11 + nBodyLen), DIRECT_ACK, wCookie, MTYPE_PLUGIN, 0, 0, 0); + // + packEmptyMsg(&packet); // Message (unused) + + packPluginTypeId(&packet, wType); + + packLEDWord(&packet, nBodyLen + 4); + packLEDWord(&packet, nBodyLen); + packBuffer(&packet, (LPBYTE)szBody, (WORD)nBodyLen); + + SendDirectMessage(hContact, &packet); +} -- cgit v1.2.3