From 51022062562449eb9679a931bdc5cb4d62aca682 Mon Sep 17 00:00:00 2001 From: aunsane Date: Sat, 3 Mar 2018 20:36:35 +0300 Subject: Tox: #1156 - more accurate transfer management - unlockong file on transfer pause - added additional logs - cleanup --- protocols/Tox/src/stdafx.h | 2 +- protocols/Tox/src/tox_avatars.cpp | 4 +- protocols/Tox/src/tox_contacts.cpp | 2 +- protocols/Tox/src/tox_proto.cpp | 6 +- protocols/Tox/src/tox_proto.h | 12 +- protocols/Tox/src/tox_transfer.cpp | 238 ++++++++++++++++++++----------------- protocols/Tox/src/tox_transfer.h | 45 ++++--- 7 files changed, 168 insertions(+), 141 deletions(-) (limited to 'protocols/Tox/src') diff --git a/protocols/Tox/src/stdafx.h b/protocols/Tox/src/stdafx.h index 0c53490d34..cb16bf8078 100644 --- a/protocols/Tox/src/stdafx.h +++ b/protocols/Tox/src/stdafx.h @@ -2,7 +2,7 @@ #define _COMMON_H_ #include -#include +#include #include #include #include diff --git a/protocols/Tox/src/tox_avatars.cpp b/protocols/Tox/src/tox_avatars.cpp index 9d234b1dd8..ad2ac177e8 100644 --- a/protocols/Tox/src/tox_avatars.cpp +++ b/protocols/Tox/src/tox_avatars.cpp @@ -189,7 +189,7 @@ INT_PTR CToxProto::SetMyAvatar(WPARAM, LPARAM lParam) return 0; } -void CToxProto::OnGotFriendAvatarInfo(AvatarTransferParam *transfer) +void CToxProto::OnGotFriendAvatarInfo(Tox *tox, AvatarTransferParam *transfer) { if (transfer->pfts.totalBytes == 0) { MCONTACT hConact = transfer->pfts.hContact; @@ -215,7 +215,7 @@ void CToxProto::OnGotFriendAvatarInfo(AvatarTransferParam *transfer) wchar_t path[MAX_PATH]; mir_snwprintf(path, L"%s\\%S", VARSW(L"%miranda_avatarcache%"), m_szModuleName); - OnFileAllow(transfer->pfts.hContact, transfer, path); + OnFileAllow(tox, transfer->pfts.hContact, transfer, path); } void CToxProto::OnGotFriendAvatarData(AvatarTransferParam *transfer) diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index a7cfc3773f..5533d78983 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -299,7 +299,7 @@ void CToxProto::OnConnectionStatusChanged(Tox *tox, uint32_t friendNumber, TOX_C proto->delSetting(hContact, "Grant"); // resume incoming transfers - proto->ResumeIncomingTransfers(friendNumber); + // proto->ResumeIncomingTransfers(friendNumber); // update avatar ptrW avatarPath(proto->GetAvatarFilePath()); diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index a6159e06f3..4b0a8581a2 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -102,7 +102,7 @@ int CToxProto::AuthRequest(MCONTACT hContact, const wchar_t *szMessage) HANDLE CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *tszPath) { - return OnFileAllow(hContact, hTransfer, tszPath); + return OnFileAllow(m_toxThread->Tox(), hContact, hTransfer, tszPath); } int CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer) @@ -117,7 +117,7 @@ int CToxProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t*) int CToxProto::FileResume(HANDLE hTransfer, int *action, const wchar_t **szFilename) { - return OnFileResume(hTransfer, action, szFilename); + return OnFileResume(m_toxThread->Tox(), hTransfer, action, szFilename); } HWND CToxProto::SearchAdvanced(HWND owner) @@ -137,7 +137,7 @@ int CToxProto::SendMsg(MCONTACT hContact, int, const char *msg) HANDLE CToxProto::SendFile(MCONTACT hContact, const wchar_t *msg, wchar_t **ppszFiles) { - return OnSendFile(hContact, msg, ppszFiles); + return OnSendFile(m_toxThread->Tox(), hContact, msg, ppszFiles); } int CToxProto::SetStatus(int iNewStatus) diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index b09ba4d4e8..8a4fd782cd 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -211,19 +211,19 @@ private: int __cdecl OnPreCreateMessage(WPARAM wParam, LPARAM lParam); // transfer - HANDLE OnFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *tszPath); - int OnFileResume(HANDLE hTransfer, int *action, const wchar_t **szFilename); - HANDLE OnSendFile(MCONTACT hContact, const wchar_t*, wchar_t **ppszFiles); + HANDLE OnFileAllow(Tox *tox, MCONTACT hContact, HANDLE hTransfer, const wchar_t *tszPath); + int OnFileResume(Tox *tox, HANDLE hTransfer, int *action, const wchar_t **szFilename); + HANDLE OnSendFile(Tox *tox, MCONTACT hContact, const wchar_t*, wchar_t **ppszFiles); int CancelTransfer(MCONTACT hContact, HANDLE hTransfer); - static void OnFileRequest(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, TOX_FILE_CONTROL control, void *arg); static void OnFriendFile(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, uint32_t kind, uint64_t fileSize, const uint8_t *fileName, size_t filenameLength, void *arg); static void OnDataReceiving(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, uint64_t position, const uint8_t *data, size_t length, void *arg); + static void OnFileRequest(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, TOX_FILE_CONTROL control, void *arg); static void OnFileSendData(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, uint64_t position, size_t length, void *arg); - void OnTransferCompleted(FileTransferParam *transfer); + void OnTransferCompleted(Tox *tox, FileTransferParam *transfer); void PauseOutgoingTransfers(uint32_t friendNumber); void ResumeIncomingTransfers(uint32_t friendNumber); @@ -238,7 +238,7 @@ private: INT_PTR __cdecl GetMyAvatar(WPARAM wParam, LPARAM lParam); INT_PTR __cdecl SetMyAvatar(WPARAM wParam, LPARAM lParam); - void OnGotFriendAvatarInfo(AvatarTransferParam *transfer); + void OnGotFriendAvatarInfo(Tox *tox, AvatarTransferParam *transfer); void OnGotFriendAvatarData(AvatarTransferParam *transfer); // utils diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp index 02dcaca5d1..fa1798d57c 100644 --- a/protocols/Tox/src/tox_transfer.cpp +++ b/protocols/Tox/src/tox_transfer.cpp @@ -3,7 +3,7 @@ /* FILE RECEIVING */ // incoming transfer flow -void CToxProto::OnFriendFile(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, uint32_t kind, uint64_t fileSize, const uint8_t *fileName, size_t filenameLength, void *arg) +void CToxProto::OnFriendFile(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, uint32_t kind, uint64_t fileSize, const uint8_t *fileName, size_t fileNameLength, void *arg) { CToxProto *proto = (CToxProto*)arg; @@ -19,7 +19,7 @@ void CToxProto::OnFriendFile(Tox *tox, uint32_t friendNumber, uint32_t fileNumbe switch (kind) { case TOX_FILE_KIND_AVATAR: { - proto->debugLogA(__FUNCTION__": incoming avatar (%d) from %s(%d)", fileNumber, (const char*)pubKey, friendNumber); + proto->debugLogA(__FUNCTION__": incoming avatar (%d) from %s (%d)", fileNumber, (const char*)pubKey, friendNumber); ptrW address(proto->getWStringA(hContact, TOX_SETTINGS_ID)); wchar_t avatarName[MAX_PATH]; @@ -33,20 +33,18 @@ void CToxProto::OnFriendFile(Tox *tox, uint32_t friendNumber, uint32_t fileNumbe TOX_ERR_FILE_GET error; tox_file_get_file_id(tox, friendNumber, fileNumber, transfer->hash, &error); if (error != TOX_ERR_FILE_GET_OK) { - Netlib_Logf(proto->m_hNetlibUser, __FUNCTION__": unable to get avatar hash (%d) from %s(%d) cause (%d)", fileNumber, (const char*)pubKey, friendNumber, error); + Netlib_Logf(proto->m_hNetlibUser, __FUNCTION__": unable to get avatar hash (%d) from %s (%d) cause (%d)", fileNumber, (const char*)pubKey, friendNumber, error); memset(transfer->hash, 0, TOX_HASH_LENGTH); } - proto->OnGotFriendAvatarInfo(transfer); + proto->OnGotFriendAvatarInfo(tox, transfer); } break; case TOX_FILE_KIND_DATA: { - proto->debugLogA(__FUNCTION__": incoming file (%d) from %s(%d)", fileNumber, (const char*)pubKey, friendNumber); + proto->debugLogA(__FUNCTION__": incoming file (%d) from %s (%d)", fileNumber, (const char*)pubKey, friendNumber); - ptrA rawName((char*)mir_alloc(filenameLength + 1)); - memcpy(rawName, fileName, filenameLength); - rawName[filenameLength] = 0; + CMStringA rawName((char*)fileName, fileNameLength); wchar_t *name = mir_utf8decodeW(rawName); FileTransferParam *transfer = new FileTransferParam(friendNumber, fileNumber, name, fileSize); @@ -66,14 +64,14 @@ void CToxProto::OnFriendFile(Tox *tox, uint32_t friendNumber, uint32_t fileNumbe break; default: - proto->debugLogA(__FUNCTION__": unsupported transfer (%d) from %s(%d) with type (%d)", fileNumber, (const char*)pubKey, friendNumber, kind); + proto->debugLogA(__FUNCTION__": unsupported transfer (%d) from %s (%d) with type (%d)", fileNumber, (const char*)pubKey, friendNumber, kind); tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); break; } } // file request is allowed -HANDLE CToxProto::OnFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *tszPath) +HANDLE CToxProto::OnFileAllow(Tox *tox, MCONTACT hContact, HANDLE hTransfer, const wchar_t *tszPath) { FileTransferParam *transfer = (FileTransferParam*)hTransfer; transfer->pfts.tszWorkingDir = mir_wstrdup(tszPath); @@ -88,7 +86,7 @@ HANDLE CToxProto::OnFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t const wchar_t **szFilename = (const wchar_t**)mir_alloc(sizeof(wchar_t*) * 2); szFilename[0] = fullPath; szFilename[1] = nullptr; - OnFileResume(hTransfer, &action, szFilename); + OnFileResume(tox, hTransfer, &action, szFilename); mir_free(szFilename); } @@ -96,12 +94,13 @@ HANDLE CToxProto::OnFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t } // if file is exists -int CToxProto::OnFileResume(HANDLE hTransfer, int *action, const wchar_t **szFilename) +int CToxProto::OnFileResume(Tox *tox, HANDLE hTransfer, int *action, const wchar_t **szFilename) { FileTransferParam *transfer = (FileTransferParam*)hTransfer; if (*action == FILERESUME_SKIP) { - tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, (HANDLE)transfer, 0); transfers.Remove(transfer); return 0; } @@ -109,46 +108,28 @@ int CToxProto::OnFileResume(HANDLE hTransfer, int *action, const wchar_t **szFil if (*action == FILERESUME_RENAME) transfer->ChangeName(*szFilename); - ToxHexAddress pubKey = GetContactPublicKey(m_toxThread->Tox(), transfer->friendNumber); + ToxHexAddress pubKey = GetContactPublicKey(tox, transfer->friendNumber); - wchar_t *mode = *action == FILERESUME_OVERWRITE ? L"wb" : L"ab"; - if (!transfer->OpenFile(mode)) { - debugLogA(__FUNCTION__": failed to open file (%d) from %s(%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); - tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + if (!transfer->Resume()) { + debugLogA(__FUNCTION__": failed to open file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); transfers.Remove(transfer); return 0; } TOX_ERR_FILE_CONTROL error; - debugLogA(__FUNCTION__": start receiving file (%d) from %s(%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); - if (!tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_RESUME, &error)) { - debugLogA(__FUNCTION__": failed to start receiving of file(%d) from %s(%d) cause (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber, error); + debugLogA(__FUNCTION__": start receiving file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + if (!tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_RESUME, &error)) { + debugLogA(__FUNCTION__": failed to start receiving of file (%d) from %s (%d) cause (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber, error); + tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); - tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); transfers.Remove(transfer); } return 0; } -void CToxProto::OnTransferCompleted(FileTransferParam *transfer) -{ - ToxHexAddress pubKey = GetContactPublicKey(m_toxThread->Tox(), transfer->friendNumber); - - debugLogA(__FUNCTION__": finised the transfer of file (%d) from %s(%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); - bool isFileFullyTransfered = transfer->pfts.currentFileProgress == transfer->pfts.currentFileSize; - if (!isFileFullyTransfered) - debugLogA(__FUNCTION__": file (%d) from %s(%d) is transferred not completely", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); - - if (transfer->transferType == TOX_FILE_KIND_AVATAR) { - OnGotFriendAvatarData((AvatarTransferParam*)transfer); - return; - } - - ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, isFileFullyTransfered ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)transfer, 0); - transfers.Remove(transfer); -} - // getting the file data void CToxProto::OnDataReceiving(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, uint64_t position, const uint8_t *data, size_t length, void *arg) { @@ -158,31 +139,37 @@ void CToxProto::OnDataReceiving(Tox *tox, uint32_t friendNumber, uint32_t fileNu FileTransferParam *transfer = proto->transfers.Get(friendNumber, fileNumber); if (transfer == nullptr) { - Netlib_Logf(proto->m_hNetlibUser, __FUNCTION__": failed to find transfer (%d) from %s (%d)", fileNumber, (const char*)pubKey, friendNumber); + proto->debugLogA(__FUNCTION__": failed to find transfer (%d) from %s (%d)", fileNumber, (const char*)pubKey, friendNumber); return; } //receiving is finished if (length == 0 || position == UINT64_MAX) { - proto->OnTransferCompleted(transfer); + proto->OnTransferCompleted(tox, transfer); return; } MCONTACT hContact = proto->GetContact(tox, friendNumber); if (hContact == NULL) { - Netlib_Logf(proto->m_hNetlibUser, __FUNCTION__": cannot find contact %s (%d)", (const char*)pubKey, friendNumber); + proto->debugLogA(__FUNCTION__": cannot find contact %s (%d)", (const char*)pubKey, friendNumber); tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); return; } uint64_t filePos = _ftelli64(transfer->hFile); - if (filePos != position) - _fseeki64(transfer->hFile, position, SEEK_SET); + if (filePos != position && !_fseeki64(transfer->hFile, position, SEEK_SET)) { + proto->debugLogA(__FUNCTION__": failed seek into file (%d)", fileNumber); + tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); + return; + } if (fwrite(data, sizeof(uint8_t), length, transfer->hFile) != length) { proto->debugLogA(__FUNCTION__": failed write to file (%d)", fileNumber); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); tox_file_control(proto->m_toxThread->Tox(), friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); return; } @@ -190,10 +177,72 @@ void CToxProto::OnDataReceiving(Tox *tox, uint32_t friendNumber, uint32_t fileNu proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts); } +void CToxProto::OnTransferCompleted(Tox *tox, FileTransferParam *transfer) +{ + ToxHexAddress pubKey = GetContactPublicKey(tox, transfer->friendNumber); + + debugLogA(__FUNCTION__": finised the transfer of file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + bool isFullyTransfered = transfer->pfts.currentFileProgress == transfer->pfts.currentFileSize; + if (!isFullyTransfered) + debugLogA(__FUNCTION__": file (%d) from %s (%d) is transferred not completely", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + + if (transfer->transferType == TOX_FILE_KIND_AVATAR) { + OnGotFriendAvatarData((AvatarTransferParam*)transfer); + return; + } + + ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, isFullyTransfered ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)transfer, 0); + transfers.Remove(transfer); +} + +void CToxProto::OnFileRequest(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, TOX_FILE_CONTROL control, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + FileTransferParam *transfer = proto->transfers.Get(friendNumber, fileNumber); + if (transfer == nullptr) { + proto->debugLogA(__FUNCTION__": failed to find transfer (%d)", fileNumber); + return; + } + + ToxHexAddress pubKey = proto->GetContactPublicKey(tox, friendNumber); + + MCONTACT hContact = proto->GetContact(tox, friendNumber); + if (hContact == NULL) { + proto->debugLogA(__FUNCTION__": cannot find contact %s (%d)", (const char*)pubKey, friendNumber); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); + return; + } + + switch (control) { + case TOX_FILE_CONTROL_PAUSE: + proto->debugLogA(__FUNCTION__": received ask to pause the transfer of file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + transfer->Pause(); + break; + + case TOX_FILE_CONTROL_RESUME: + proto->debugLogA(__FUNCTION__": received ask to resume the transfer of file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + if (!transfer->Resume()) { + proto->debugLogA(__FUNCTION__": failed to resume file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); + } + break; + + case TOX_FILE_CONTROL_CANCEL: + proto->debugLogA(__FUNCTION__": received ask to cancel the transfer of file (%d) from %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); + break; + } +} + /* FILE SENDING */ // outcoming file flow -HANDLE CToxProto::OnSendFile(MCONTACT hContact, const wchar_t*, wchar_t **ppszFiles) +HANDLE CToxProto::OnSendFile(Tox *tox, MCONTACT hContact, const wchar_t*, wchar_t **ppszFiles) { int32_t friendNumber = GetToxFriendNumber(hContact); if (friendNumber == UINT32_MAX) @@ -215,18 +264,17 @@ HANDLE CToxProto::OnSendFile(MCONTACT hContact, const wchar_t*, wchar_t **ppszFi uint64_t fileSize = _ftelli64(hFile); rewind(hFile); - ToxHexAddress pubKey = GetContactPublicKey(m_toxThread->Tox(), friendNumber); + ToxHexAddress pubKey = GetContactPublicKey(tox, friendNumber); - char *name = mir_utf8encodeW(fileName); + T2Utf rawName(fileName); TOX_ERR_FILE_SEND sendError; - uint32_t fileNumber = tox_file_send(m_toxThread->Tox(), friendNumber, TOX_FILE_KIND_DATA, fileSize, nullptr, (uint8_t*)name, mir_strlen(name), &sendError); + uint32_t fileNumber = tox_file_send(tox, friendNumber, TOX_FILE_KIND_DATA, fileSize, nullptr, (uint8_t*)(char*)rawName, mir_strlen(rawName), &sendError); if (sendError != TOX_ERR_FILE_SEND_OK) { debugLogA(__FUNCTION__": failed to send file (%d) to %s(%d) cause (%d)", fileNumber, (const char*)pubKey, friendNumber, sendError); mir_free(fileDir); - mir_free(name); return nullptr; } - debugLogA(__FUNCTION__": start sending file (%d) to %s(%d)", fileNumber, (const char*)pubKey, friendNumber); + debugLogA(__FUNCTION__": start sending file (%d) to %s (%d)", fileNumber, (const char*)pubKey, friendNumber); FileTransferParam *transfer = new FileTransferParam(friendNumber, fileNumber, fileName, fileSize); transfer->pfts.flags |= PFTS_SENDING; @@ -235,7 +283,6 @@ HANDLE CToxProto::OnSendFile(MCONTACT hContact, const wchar_t*, wchar_t **ppszFi transfer->hFile = hFile; transfers.Add(transfer); - mir_free(name); return (HANDLE)transfer; } @@ -247,52 +294,54 @@ void CToxProto::OnFileSendData(Tox *tox, uint32_t friendNumber, uint32_t fileNum FileTransferParam *transfer = proto->transfers.Get(friendNumber, fileNumber); if (!transfer) { - proto->debugLogA(__FUNCTION__": failed to find transfer (%d) to %s(%d)", fileNumber, (const char*)pubKey, friendNumber); + proto->debugLogA(__FUNCTION__": failed to find transfer (%d) to %s (%d)", fileNumber, (const char*)pubKey, friendNumber); tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); return; } if (length == 0) { // file sending is finished - proto->debugLogA(__FUNCTION__": finised the transfer of file (%d) to %s(%d)", fileNumber, (const char*)pubKey, friendNumber); - bool isFileFullyTransfered = transfer->pfts.currentFileProgress == transfer->pfts.currentFileSize; - if (!isFileFullyTransfered) - proto->debugLogA(__FUNCTION__": file (%d) is not completely transferred to %s(%d)", fileNumber, (const char*)pubKey, friendNumber); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, isFileFullyTransfered ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->debugLogA(__FUNCTION__": finised the transfer of file (%d) to %s (%d)", fileNumber, (const char*)pubKey, friendNumber); + bool isFullyTransfered = transfer->pfts.currentFileProgress == transfer->pfts.currentFileSize; + if (!isFullyTransfered) + proto->debugLogA(__FUNCTION__": file (%d) is not completely transferred to %s (%d)", fileNumber, (const char*)pubKey, friendNumber); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, isFullyTransfered ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)transfer, 0); proto->transfers.Remove(transfer); return; } uint64_t sentBytes = _ftelli64(transfer->hFile); - if (sentBytes != position) - _fseeki64(transfer->hFile, position, SEEK_SET); + if (sentBytes != position && !_fseeki64(transfer->hFile, position, SEEK_SET)) { + proto->debugLogA(__FUNCTION__": failed seek into file (%d)", fileNumber); + tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); + return; + } - uint8_t *data = (uint8_t*)mir_alloc(length); + mir_ptr data((uint8_t*)mir_alloc(length)); if (fread(data, sizeof(uint8_t), length, transfer->hFile) != length) { - proto->debugLogA(__FUNCTION__": failed to read from file (%d) to %s(%d)", fileNumber, (const char*)pubKey, friendNumber); + proto->debugLogA(__FUNCTION__": failed to read from file (%d) to %s (%d)", fileNumber, (const char*)pubKey, friendNumber); proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); - tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); - mir_free(data); + tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); + proto->transfers.Remove(transfer); return; } TOX_ERR_FILE_SEND_CHUNK error; if (!tox_file_send_chunk(proto->m_toxThread->Tox(), friendNumber, fileNumber, position, data, length, &error)) { - if (error == TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED) { - mir_free(data); + if (error == TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED) return; - } - proto->debugLogA(__FUNCTION__": failed to send file chunk (%d) to %s(%d) cause (%d)", fileNumber, (const char*)pubKey, friendNumber, error); + proto->debugLogA(__FUNCTION__": failed to send file chunk (%d) to %s (%d) cause (%d)", fileNumber, (const char*)pubKey, friendNumber, error); + tox_file_control(tox, friendNumber, fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); - tox_file_control(proto->m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); - mir_free(data); + proto->transfers.Remove(transfer); return; } transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += length; proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts); - - mir_free(data); } /* COMMON */ @@ -300,7 +349,7 @@ void CToxProto::OnFileSendData(Tox *tox, uint32_t friendNumber, uint32_t fileNum int CToxProto::CancelTransfer(MCONTACT, HANDLE hTransfer) { FileTransferParam *transfer = (FileTransferParam*)hTransfer; - debugLogA(__FUNCTION__": Transfer (%d) is canceled", transfer->fileNumber); + debugLogA(__FUNCTION__": transfer (%d) is canceled", transfer->fileNumber); tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); transfers.Remove(transfer); @@ -315,10 +364,10 @@ void CToxProto::PauseOutgoingTransfers(uint32_t friendNumber) if (transfer->friendNumber == friendNumber && transfer->GetDirection() == 0) { ToxHexAddress pubKey = GetContactPublicKey(m_toxThread->Tox(), friendNumber); - debugLogA(__FUNCTION__": sending ask to pause the transfer of file (%d) to %s(%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); + debugLogA(__FUNCTION__": sending ask to pause the transfer of file (%d) to %s (%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber); TOX_ERR_FILE_CONTROL error; if (!tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_PAUSE, &error)) { - debugLogA(__FUNCTION__": failed to pause the transfer (%d) to %s(%d) cause(%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber, error); + debugLogA(__FUNCTION__": failed to pause the transfer (%d) to %s (%d) cause(%d)", transfer->fileNumber, (const char*)pubKey, transfer->friendNumber, error); tox_file_control(m_toxThread->Tox(), transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); } } @@ -345,44 +394,11 @@ void CToxProto::ResumeIncomingTransfers(uint32_t friendNumber) void CToxProto::CancelAllTransfers(Tox *tox) { + debugLogA(__FUNCTION__": canceling all transfers"); for (size_t i = 0; i < transfers.Count(); i++) { FileTransferParam *transfer = transfers.GetAt(i); tox_file_control(tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, nullptr); ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); transfers.Remove(transfer); } -} - -void CToxProto::OnFileRequest(Tox *tox, uint32_t friendNumber, uint32_t fileNumber, TOX_FILE_CONTROL control, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - FileTransferParam *transfer = proto->transfers.Get(friendNumber, fileNumber); - if (transfer == nullptr) { - proto->debugLogA(__FUNCTION__": failed to find transfer (%d)", fileNumber); - return; - } - - ToxHexAddress pubKey = proto->GetContactPublicKey(tox, friendNumber); - - MCONTACT hContact = proto->GetContact(tox, friendNumber); - if (hContact == NULL) { - Netlib_Logf(proto->m_hNetlibUser, __FUNCTION__": cannot find contact %s (%d)", (const char*)pubKey, friendNumber); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); - proto->transfers.Remove(transfer); - return; - } - - switch (control) { - case TOX_FILE_CONTROL_PAUSE: - break; - - case TOX_FILE_CONTROL_RESUME: - break; - - case TOX_FILE_CONTROL_CANCEL: - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); - proto->transfers.Remove(transfer); - break; - } -} +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_transfer.h b/protocols/Tox/src/tox_transfer.h index 640a4f1305..8b0a30cb32 100644 --- a/protocols/Tox/src/tox_transfer.h +++ b/protocols/Tox/src/tox_transfer.h @@ -34,12 +34,36 @@ struct FileTransferParam transferType = TOX_FILE_KIND_DATA; } - bool OpenFile(const wchar_t *mode) + ~FileTransferParam() { - hFile = _wfopen(pfts.tszCurrentFile, mode); + if (pfts.tszWorkingDir) + mir_free(pfts.tszWorkingDir); + mir_free(pfts.pszFiles[0]); + mir_free(pfts.pszFiles); + if (hFile) { + fclose(hFile); + hFile = nullptr; + } + } + + bool Resume() + { + if (hFile) + return true; + hFile = _wfopen(pfts.tszCurrentFile, L"wb+"); + if (hFile) + _chsize_s(_fileno(hFile), pfts.currentFileSize); return hFile != nullptr; } + void Pause() + { + if (hFile) { + fclose(hFile); + hFile = nullptr; + } + } + void ChangeName(const wchar_t *fileName) { pfts.ptszFiles[0] = replaceStrW(pfts.tszCurrentFile, fileName); @@ -49,19 +73,6 @@ struct FileTransferParam { return (pfts.flags & PFTS_SENDING) ? 0 : 1; } - - ~FileTransferParam() - { - if (pfts.tszWorkingDir != nullptr) - mir_free(pfts.tszWorkingDir); - mir_free(pfts.pszFiles[0]); - mir_free(pfts.pszFiles); - if (hFile != nullptr) - { - fclose(hFile); - hFile = nullptr; - } - } }; struct AvatarTransferParam : public FileTransferParam @@ -114,8 +125,8 @@ public: { if (transfer == nullptr) return; - transfers.erase(transfer->transferNumber); - delete transfer; + if (transfers.erase(transfer->transferNumber)) + delete transfer; } }; -- cgit v1.2.3