From c015ec458520935c407aa1b2ce1d004c5c5c8a61 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 Apr 2014 08:46:04 +0000 Subject: ICQCorp adopted - needs Unicode fixes git-svn-id: http://svn.miranda-ng.org/main/trunk@8980 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/ICQCorp/src/transfer.cpp | 505 +++++++++++++++++++++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100644 protocols/ICQCorp/src/transfer.cpp (limited to 'protocols/ICQCorp/src/transfer.cpp') diff --git a/protocols/ICQCorp/src/transfer.cpp b/protocols/ICQCorp/src/transfer.cpp new file mode 100644 index 0000000000..eb1a8dbf7b --- /dev/null +++ b/protocols/ICQCorp/src/transfer.cpp @@ -0,0 +1,505 @@ +/* + ICQ Corporate protocol plugin for Miranda IM. + Copyright (C) 2003-2005 Eugene Tarasenko + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "corp.h" + +std::vector icqTransfers; + +/////////////////////////////////////////////////////////////////////////////// + +void WINAPI transferTimerProc(HWND hWnd, UINT Msg, UINT_PTR hTimer, DWORD Time) +{ + unsigned int i; + + KillTimer(NULL, hTimer); + for (i=0; ihTimer) icqTransfers[i]->process(); +} + +/////////////////////////////////////////////////////////////////////////////// + +ICQTransfer::ICQTransfer(ICQUser *u, unsigned int theSequence) : + socket(WM_NETEVENT_TRANSFER) +{ + uin = u->uin; + hContact = u->hContact; + sequence = theSequence; + files = NULL; + description = NULL; + path = NULL; + sending = 0; + speed = 100; + count = 0; + current = -1; + fileName = NULL; + fileSize = 0; + fileProgress = 0; + totalSize = 0; + totalProgress = 0; + lastNotify = 0; + hTimer = NULL; + hFile = INVALID_HANDLE_VALUE; +} + +/////////////////////////////////////////////////////////////////////////////// + +ICQTransfer::~ICQTransfer() +{ + closeFile(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::processTcpPacket(Packet &packet) +{ + unsigned int /*i,*/ status, junkLong; + //unsigned short junkShort; + unsigned char cmd/*, junkChar*/; + char *name = NULL, *directoryName = NULL; + + packet >> cmd; + switch (cmd) + { + case 0x00: + T("[tcp] recieve initialising file transfer\n"); + packet >> junkLong + >> count + >> totalSize + >> speed + >> name; + + files = new char*[count + 1]; + ZeroMemory(files, (count+1)*sizeof(char*)); + + ack(ACKRESULT_INITIALISING); + sendPacket0x01(); + break; + + case 0x01: + T("[tcp] ack initialising\n"); + packet >> speed + >> name; + + ack(ACKRESULT_INITIALISING); + sendPacket0x02(); + break; + + case 0x02: + T("[tcp] recieve next file\n"); + packet >> directory + >> files[++current] + >> directoryName + >> fileSize + >> fileDate + >> speed; + + if (directoryName[0]) + { + char *fullName = new char[strlen(directoryName) + strlen(files[current]) + 2]; + sprintf(fullName, "%s\\%s", directoryName, files[current]); + delete [] files[current]; + files[current] = fullName; + } + + if (directory) createDirectory(); + else openFile(); + ack(ACKRESULT_NEXTFILE); + + if (fileProgress) ack(ACKRESULT_FILERESUME); + else sendPacket0x03(); + break; + + case 0x03: + T("[tcp] ack next file\n"); + packet >> fileProgress + >> status + >> speed; + + totalProgress += fileProgress; + setFilePosition(); + ack(ACKRESULT_NEXTFILE); + + if (status != 0) + { + totalProgress += fileSize - fileProgress; + fileProgress = fileSize; + closeFile(); + ack(ACKRESULT_DATA); + } + + process(); + break; + + case 0x04: + T("[tcp] recieve stop file\n"); + packet >> junkLong; + + totalProgress += fileSize - fileProgress; + fileProgress = fileSize; + closeFile(); + ack(ACKRESULT_DATA); + break; + + case 0x05: + T("[tcp] recieve new speed\n"); + packet >> speed; + break; + + case 0x06: + unsigned long result; + + WriteFile(hFile, packet.data(), packet.dataSize(), &result, NULL); + + fileProgress += result; + totalProgress += result; + + if (fileProgress >= fileSize) closeFile(); + ack(ACKRESULT_DATA); + break; + + default: + T("[tcp] unknown packet:\n%s", packet.print()); + packet.reset(); + } + + delete [] directoryName; + delete [] name; +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x00() +{ + char nick[1] = { 0 }; + + sending = true; + + Packet packet; + packet << (unsigned char)0x00 + << (unsigned int)0x00 + << count + << totalSize + << speed + << nick; + + T("[tcp] send packet 0x00\n"); + socket.sendPacket(packet); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x01() +{ + char nick[1] = { 0 }; + + Packet packet; + packet << (unsigned char)0x01 + << speed + << nick; + + T("[tcp] send packet 0x01\n"); + socket.sendPacket(packet); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x02() +{ + char *directoryName, *p; + + current++; + openFile(); + + directoryName = _strdup(fileName); + p = strrchr(directoryName, '\\'); + p[0] = 0; + p[1] = 0; + + Packet packet; + packet << (unsigned char)0x02 + << directory + << (strrchr(fileName, '\\') + 1) + << (directoryName + strlen(path) + 1) + << fileSize + << fileDate + << speed; + + T("[tcp] send packet 0x02\n"); + socket.sendPacket(packet); + ack(ACKRESULT_NEXTFILE); + + free(directoryName); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x03() +{ + Packet packet; + packet << (unsigned char)0x03 + << fileProgress + << (unsigned int)0x00 + << speed; + + setFilePosition(); + + T("[tcp] send packet 0x03\n"); + socket.sendPacket(packet); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x04() +{ + T("[tcp] send packet 0x04\n"); +/* + icq_PacketAppend8(p, 0x04); + icq_PacketAppend32(p, filenum); +*/ +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x05() +{ + T("[tcp] send packet 0x05\n"); +/* + icq_PacketAppend8(p, 0x05); + icq_PacketAppend32(p, speed); +*/ +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::sendPacket0x06() +{ + unsigned long result; + + Packet packet; + packet << (unsigned char)0x06; + + ReadFile(hFile, packet.data(), 2048, &result, NULL); + if (result == 0) return; + packet.add(result); + +// T("[tcp] send packet 0x06\n"); + socket.sendPacket(packet); + + fileProgress += result; + totalProgress += result; + + if (fileProgress >= fileSize) closeFile(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::ack(unsigned int result) +{ + PROTOFILETRANSFERSTATUS fts; + + if (result == ACKRESULT_DATA && GetTickCount() < lastNotify+250 && fileProgress < fileSize) return; + + fts.cbSize = sizeof(fts); + fts.hContact = hContact; + //fts.sending = sending; + fts.pszFiles = files; + fts.totalFiles = count; + fts.currentFileNumber = current; + fts.totalBytes = totalSize; + fts.totalProgress = totalProgress; + fts.szWorkingDir = path; + fts.szCurrentFile = fileName; + fts.currentFileSize = fileSize; + fts.currentFileProgress = fileProgress; + fts.currentFileTime = CallService(MS_DB_TIME_TIMESTAMPTOLOCAL, fileDate, 0); +/* + switch (session->status) + { + case FILE_STATUS_LISTENING: result = ACKRESULT_SENTREQUEST; break; + case FILE_STATUS_CONNECTED: result = ACKRESULT_CONNECTED; break; + case FILE_STATUS_CONNECTING: result = ACKRESULT_CONNECTING; break; + case FILE_STATUS_INITIALIZING: result = ACKRESULT_INITIALISING; break; + case FILE_STATUS_NEXT_FILE: result = ACKRESULT_NEXTFILE; break; + case FILE_STATUS_SENDING: + case FILE_STATUS_RECEIVING: result=ACKRESULT_DATA; break; + } +*/ + ProtoBroadcastAck(protoName, hContact, ACKTYPE_FILE, result, this, (LPARAM)&fts); + lastNotify = GetTickCount(); + + if (result == ACKRESULT_DATA && current >= count-1 && fileProgress >= fileSize) + { + ProtoBroadcastAck(protoName, hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, this, 0); + socket.closeConnection(); + + unsigned int i; + for (i=0; i= count) return; + + startTime = GetTickCount(); + while (fileProgress < fileSize && GetTickCount() < startTime+100) sendPacket0x06(); + ack(ACKRESULT_DATA); + + if (fileProgress < fileSize) hTimer = SetTimer(NULL, 0, 1, (TIMERPROC)transferTimerProc); + else if (current < count-1) sendPacket0x02(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::resume(int action, const char *newName) +{ + switch (action) + { + case FILERESUME_OVERWRITE: + T("[ ] overwrite existing file\n"); + fileProgress = 0; + break; + + case FILERESUME_RESUME: + T("[ ] file resume\n"); + break; + + case FILERESUME_RENAME: + T("[ ] rename file\n"); + delete [] fileName; + fileName = new char[strlen(newName) + 1]; + strcpy(fileName, newName); + files[current] = fileName; + + openFile(); + fileProgress = 0; + break; + + case FILERESUME_SKIP: + T("[ ] skip file\n"); + fileProgress = fileSize; + break; + } + + totalProgress += fileProgress; + + sendPacket0x03(); + ack(ACKRESULT_NEXTFILE); + + if (fileProgress) ack(ACKRESULT_DATA); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::openFile() +{ + HANDLE hFind; + WIN32_FIND_DATA findData; + __int64 fileTime; + + if (hFile != INVALID_HANDLE_VALUE) closeFile(); + if (path) SetCurrentDirectory(path); + + fileName = files[current]; + + hFind = FindFirstFile(fileName, &findData); + if (hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + T("open directory %s\n", fileName); + directory = 1; + fileProgress = 0; + fileSize = 0; + fileDate = *(__int64*)(&findData.ftLastWriteTime) / 10000000 - 11644473600i64; + return; + } + } + directory = 0; + + hFile = CreateFile(fileName, sending ? GENERIC_READ : GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + char msg[2048]; + + T("can't open file %s\n", fileName); + sprintf(msg, "%s\n%s", sending ? Translate("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.") : Translate("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."), fileName); + MessageBox(NULL, msg, Translate(protoName), MB_ICONWARNING|MB_OK); + return; + } + + if (sending) + { + fileProgress = 0; + fileSize = GetFileSize(hFile, NULL); + + GetFileTime(hFile, NULL, NULL, (LPFILETIME)&fileTime); + fileDate = fileTime / 10000000 - 11644473600i64; + } + else + { + fileProgress = GetFileSize(hFile, NULL); + + fileTime = (11644473600i64 + (__int64)fileDate) * 10000000; + SetFileTime(hFile, NULL, NULL, (LPFILETIME)&fileTime); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::closeFile() +{ + CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::setFilePosition() +{ + if (hFile != INVALID_HANDLE_VALUE) SetFilePointer(hFile, fileProgress, NULL, FILE_BEGIN); +} + +/////////////////////////////////////////////////////////////////////////////// + +void ICQTransfer::createDirectory() +{ + if (path) SetCurrentDirectory(path); + + fileName = files[current]; + CreateDirectory(fileName, NULL); + + fileProgress = 0; +} + +/////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3