summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2018-03-03 20:36:35 +0300
committeraunsane <aunsane@gmail.com>2018-03-03 20:36:35 +0300
commit51022062562449eb9679a931bdc5cb4d62aca682 (patch)
tree93a56d484b80b0eab1eebef9e1fb067d7ea3e7be /protocols
parentfa58f69fe117640e29cefb1b699bede4d045bc2f (diff)
Tox: #1156
- more accurate transfer management - unlockong file on transfer pause - added additional logs - cleanup
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Tox/Tox.vcxproj3
-rw-r--r--protocols/Tox/libtox/src/libtox.def2
-rw-r--r--protocols/Tox/src/stdafx.h2
-rw-r--r--protocols/Tox/src/tox_avatars.cpp4
-rw-r--r--protocols/Tox/src/tox_contacts.cpp2
-rw-r--r--protocols/Tox/src/tox_proto.cpp6
-rw-r--r--protocols/Tox/src/tox_proto.h12
-rw-r--r--protocols/Tox/src/tox_transfer.cpp238
-rw-r--r--protocols/Tox/src/tox_transfer.h45
9 files changed, 169 insertions, 145 deletions
diff --git a/protocols/Tox/Tox.vcxproj b/protocols/Tox/Tox.vcxproj
index 17ed280c21..a550839300 100644
--- a/protocols/Tox/Tox.vcxproj
+++ b/protocols/Tox/Tox.vcxproj
@@ -29,9 +29,6 @@
<ClCompile>
<AdditionalIncludeDirectories>..\..\include;libtox\src\toxcore;libtox\src\toxencryptsave;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
- <Link>
- <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
diff --git a/protocols/Tox/libtox/src/libtox.def b/protocols/Tox/libtox/src/libtox.def
index 7d27a74f5e..c8c75b267b 100644
--- a/protocols/Tox/libtox/src/libtox.def
+++ b/protocols/Tox/libtox/src/libtox.def
@@ -7,7 +7,7 @@ tox_address_size
tox_bootstrap
tox_callback_conference_invite
tox_callback_conference_message
-tox_callback_conference_namelist_change
+tox_callback_conference_peer_list_changed
tox_callback_conference_title
tox_callback_file_chunk_request
tox_callback_file_recv
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 <windows.h>
-#include <windns.h>
+#include <io.h>
#include <time.h>
#include <commctrl.h>
#include <msapi/comptr.h>
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<uint8_t> 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;
}
};