summaryrefslogtreecommitdiff
path: root/protocols/MRA/src/MraFilesQueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/MRA/src/MraFilesQueue.cpp')
-rw-r--r--protocols/MRA/src/MraFilesQueue.cpp1146
1 files changed, 0 insertions, 1146 deletions
diff --git a/protocols/MRA/src/MraFilesQueue.cpp b/protocols/MRA/src/MraFilesQueue.cpp
deleted file mode 100644
index dee5082350..0000000000
--- a/protocols/MRA/src/MraFilesQueue.cpp
+++ /dev/null
@@ -1,1146 +0,0 @@
-#include "stdafx.h"
-#include "MraFilesQueue.h"
-#include "proto.h"
-
-#define MRA_FT_HELLO "MRA_FT_HELLO"
-#define MRA_FT_GET_FILE "MRA_FT_GET_FILE"
-
-struct MRA_FILES_QUEUE : public LIST_MT
-{
- DWORD dwSendTimeOutInterval;
-};
-
-struct MRA_FILES_QUEUE_FILE
-{
- LPWSTR lpwszName;
- size_t dwNameLen;
- DWORDLONG dwSize;
-};
-
-struct MRA_FILES_QUEUE_ITEM : public LIST_MT_ITEM
-{
- // internal
- bool bIsWorking;
- DWORD dwSendTime;
-
- // external
- CMraProto *ppro;
- DWORD dwIDRequest;
- DWORD dwFlags;
- MCONTACT hContact;
- DWORDLONG dwFilesCount;
- DWORDLONG dwFilesTotalSize;
- MRA_FILES_QUEUE_FILE *pmfqfFiles;
- LPWSTR pwszFilesList;
- LPWSTR pwszDescription;
- MRA_ADDR_LIST malAddrList;
- LPWSTR lpwszPath;
- size_t dwPathSize;
- bool bSending;
- HNETLIBCONN hConnection;
- HANDLE hListen;
- HANDLE hThread;
- HANDLE hWaitHandle;
- HANDLE hMraMrimProxyData;
-};
-
-struct MRA_FILES_THREADPROC_PARAMS
-{
- HANDLE hFilesQueueHandle;
- MRA_FILES_QUEUE_ITEM *dat;
-};
-
-DWORD MraFilesQueueItemFindByID(HANDLE hQueue, DWORD dwIDRequest, MRA_FILES_QUEUE_ITEM **ppmrafqFilesQueueItem);
-void MraFilesQueueItemFree(MRA_FILES_QUEUE_ITEM *dat);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// File transfer options
-
-static WORD wMraFilesControlsList[] = {
- IDC_FILE_SEND_NOOUTCONNECTIONONRECEIVE,
- IDC_FILE_SEND_NOOUTCONNECTIONONSEND,
- IDC_FILE_SEND_IGNORYADDITIONALPORTS,
- IDC_FILE_SEND_HIDE_MY_ADDRESSES,
- IDC_FILE_SEND_ADD_EXTRA_ADDRESS,
- IDC_FILE_SEND_EXTRA_ADDRESS
-};
-
-void MraFilesQueueDlgEnableDirectConsControls(HWND hWndDlg, BOOL bEnabled)
-{
- EnableControlsArray(hWndDlg, (WORD*)&wMraFilesControlsList, _countof(wMraFilesControlsList), bEnabled);
- EnableWindow(GetDlgItem(hWndDlg, IDC_FILE_SEND_EXTRA_ADDRESS), (bEnabled && IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ADD_EXTRA_ADDRESS)));
-}
-
-INT_PTR CALLBACK MraFilesQueueDlgProcOpts(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CMraProto *ppro = (CMraProto*)GetWindowLongPtr(hWndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hWndDlg);
- SetWindowLongPtr(hWndDlg, GWLP_USERDATA, lParam);
- ppro = (CMraProto*)lParam;
- {
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_ENABLE_DIRECT_CONN, ppro->getByte("FileSendEnableDirectConn", MRA_DEF_FS_ENABLE_DIRECT_CONN) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_NOOUTCONNECTIONONRECEIVE, ppro->getByte("FileSendNoOutConnOnRcv", MRA_DEF_FS_NO_OUT_CONN_ON_RCV) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_NOOUTCONNECTIONONSEND, ppro->getByte("FileSendNoOutConnOnSend", MRA_DEF_FS_NO_OUT_CONN_ON_SEND) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_IGNORYADDITIONALPORTS, ppro->getByte("FileSendIgnoryAdditionalPorts", MRA_DEF_FS_IGNORY_ADDITIONAL_PORTS) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_HIDE_MY_ADDRESSES, ppro->getByte("FileSendHideMyAddresses", MRA_DEF_FS_HIDE_MY_ADDRESSES) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_ADD_EXTRA_ADDRESS, ppro->getByte("FileSendAddExtraAddresses", MRA_DEF_FS_ADD_EXTRA_ADDRESSES) ? BST_CHECKED : BST_UNCHECKED);
-
- CMStringW szBuff;
- if (ppro->mraGetStringW(NULL, "FileSendExtraAddresses", szBuff))
- SetDlgItemText(hWndDlg, IDC_FILE_SEND_EXTRA_ADDRESS, szBuff.c_str());
-
- CheckDlgButton(hWndDlg, IDC_FILE_SEND_ENABLE_MRIMPROXY_CONS, ppro->getByte("FileSendEnableMRIMProxyCons", MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS) ? BST_CHECKED : BST_UNCHECKED);
-
- SetDlgItemInt(hWndDlg, IDC_FILE_SEND_BLOCK_SIZE, ppro->getDword("FileSendBlockSize", MRA_DEFAULT_FILE_SEND_BLOCK_SIZE), FALSE);
-
- MraFilesQueueDlgEnableDirectConsControls(hWndDlg, IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ENABLE_DIRECT_CONN));
- }
- return TRUE;
-
- case WM_COMMAND:
- if (LOWORD(wParam) == IDC_FILE_SEND_ENABLE_DIRECT_CONN)
- MraFilesQueueDlgEnableDirectConsControls(hWndDlg, IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ENABLE_DIRECT_CONN));
-
- if (LOWORD(wParam) == IDC_FILE_SEND_ADD_EXTRA_ADDRESS)
- EnableWindow(GetDlgItem(hWndDlg, IDC_FILE_SEND_EXTRA_ADDRESS), IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ADD_EXTRA_ADDRESS));
-
- if ((LOWORD(wParam) == IDC_FILE_SEND_EXTRA_ADDRESS || LOWORD(wParam) == IDC_FILE_SEND_BLOCK_SIZE) && (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())) return FALSE;
- SendMessage(GetParent(hWndDlg), PSM_CHANGED, 0, 0);
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- ppro->setByte("FileSendEnableDirectConn", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ENABLE_DIRECT_CONN));
- ppro->setByte("FileSendNoOutConnOnRcv", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_NOOUTCONNECTIONONRECEIVE));
- ppro->setByte("FileSendNoOutConnOnSend", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_NOOUTCONNECTIONONSEND));
- ppro->setByte("FileSendIgnoryAdditionalPorts", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_IGNORYADDITIONALPORTS));
- ppro->setByte("FileSendHideMyAddresses", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_HIDE_MY_ADDRESSES));
- ppro->setByte("FileSendAddExtraAddresses", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ADD_EXTRA_ADDRESS));
-
- WCHAR szBuff[MAX_PATH];
- GetDlgItemText(hWndDlg, IDC_FILE_SEND_EXTRA_ADDRESS, szBuff, _countof(szBuff));
- ppro->mraSetStringW(NULL, "FileSendExtraAddresses", szBuff);
- ppro->setDword("FileSendBlockSize", (DWORD)GetDlgItemInt(hWndDlg, IDC_FILE_SEND_BLOCK_SIZE, nullptr, FALSE));
- ppro->setByte("FileSendEnableMRIMProxyCons", IsDlgButtonChecked(hWndDlg, IDC_FILE_SEND_ENABLE_MRIMPROXY_CONS));
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// MRA files' queue
-
-DWORD MraFilesQueueInitialize(DWORD dwSendTimeOutInterval, HANDLE *phFilesQueueHandle)
-{
- if (!phFilesQueueHandle)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = new MRA_FILES_QUEUE();
- if (!pmrafqFilesQueue)
- return GetLastError();
-
- pmrafqFilesQueue->dwSendTimeOutInterval = dwSendTimeOutInterval;
- *phFilesQueueHandle = (HANDLE)pmrafqFilesQueue;
- return NO_ERROR;
-}
-
-void MraFilesQueueDestroy(HANDLE hQueue)
-{
- if (!hQueue)
- return;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
- {
- mir_cslock l(pmrafqFilesQueue->cs);
- while (ListMTItemGetFirst(pmrafqFilesQueue, nullptr, (LPVOID*)&dat) == NO_ERROR)
- MraFilesQueueItemFree(dat);
- }
- delete pmrafqFilesQueue;
-}
-
-DWORD MraFilesQueueItemFindByID(HANDLE hQueue, DWORD dwIDRequest, MRA_FILES_QUEUE_ITEM **ppmrafqFilesQueueItem)
-{
- if (!hQueue)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
- LIST_MT_ITERATOR lmtiIterator;
-
- mir_cslock l(pmrafqFilesQueue->cs);
- ListMTIteratorMoveFirst(pmrafqFilesQueue, &lmtiIterator);
- do {
- if (ListMTIteratorGet(&lmtiIterator, nullptr, (LPVOID*)&dat) == NO_ERROR)
- if (dat->dwIDRequest == dwIDRequest) {
- if (ppmrafqFilesQueueItem)
- *ppmrafqFilesQueueItem = dat;
- return 0;
- }
- }
- while (ListMTIteratorMoveNext(&lmtiIterator));
-
- return ERROR_NOT_FOUND;
-}
-
-HANDLE MraFilesQueueItemProxyByID(HANDLE hQueue, DWORD dwIDRequest)
-{
- MRA_FILES_QUEUE_ITEM *dat;
- if (!MraFilesQueueItemFindByID(hQueue, dwIDRequest, &dat))
- return dat->hMraMrimProxyData;
-
- return nullptr;
-}
-
-void MraFilesQueueItemFree(MRA_FILES_QUEUE_ITEM *dat)
-{
- LIST_MT *plmtListMT = (LIST_MT*)dat->lpListMT;
-
- for (size_t i = 0; i < dat->dwFilesCount; i++)
- mir_free(dat->pmfqfFiles[i].lpwszName);
-
- mir_free(dat->pmfqfFiles);
- mir_free(dat->pwszFilesList);
- mir_free(dat->pwszDescription);
- MraAddrListFree(&dat->malAddrList);
- MraMrimProxyFree(dat->hMraMrimProxyData);
- mir_free(dat->lpwszPath);
- {
- mir_cslock l(plmtListMT->cs);
- ListMTItemDelete(plmtListMT, dat);
- }
- mir_free(dat);
-}
-
-size_t CMraProto::MraFilesQueueGetLocalAddressesList(LPSTR lpszBuff, size_t dwBuffSize, DWORD dwPort)
-{
- LPSTR lpszCurPos = lpszBuff;
-
- if (getByte("FileSendHideMyAddresses", MRA_DEF_FS_HIDE_MY_ADDRESSES)) {// не выдаём врагу наш IP адрес!!! :)
- if (getByte("FileSendAddExtraAddresses", MRA_DEF_FS_ADD_EXTRA_ADDRESSES) == FALSE) {// только если не добавляем адрес роутера
- lpszCurPos += mir_snprintf(lpszCurPos, (dwBuffSize - ((size_t)lpszCurPos - (size_t)lpszBuff)), MRA_FILES_NULL_ADDRR);
- }
- }
- else {// создаём список наших IP адресов
- BYTE btAddress[32];
- DWORD dwSelfExternalIP;
- size_t dwAdapter = 0;
- hostent *sh;
-
- dwSelfExternalIP = ntohl(getDword("IP", 0));
- if (dwSelfExternalIP) {
- memcpy(&btAddress, &dwSelfExternalIP, sizeof(DWORD));
- lpszCurPos += mir_snprintf(lpszCurPos, (dwBuffSize - ((size_t)lpszCurPos - (size_t)lpszBuff)), "%lu.%lu.%lu.%lu:%lu;", btAddress[0], btAddress[1], btAddress[2], btAddress[3], dwPort);
- }
-
- CHAR szHostName[MAX_PATH] = { 0 };
- if (gethostname(szHostName, _countof(szHostName)) == 0)
- if ((sh = gethostbyname((LPSTR)&szHostName))) {
- while (sh->h_addr_list[dwAdapter]) {
- lpszCurPos += mir_snprintf(lpszCurPos, (dwBuffSize - ((size_t)lpszCurPos - (size_t)lpszBuff)), "%s:%lu;", inet_ntoa(*((struct in_addr*)sh->h_addr_list[dwAdapter])), dwPort);
- dwAdapter++;
- }
- }
- }
-
- CMStringA szHostName;
- if (getByte("FileSendAddExtraAddresses", MRA_DEF_FS_ADD_EXTRA_ADDRESSES))// добавляем произвольный адрес
- if (mraGetStringA(NULL, "FileSendExtraAddresses", szHostName))
- lpszCurPos += mir_snprintf(lpszCurPos, (dwBuffSize - ((size_t)lpszCurPos - (size_t)lpszBuff)), "%s:%lu;", szHostName.c_str(), dwPort);
-
- return lpszCurPos - lpszBuff;
-}
-
-DWORD CMraProto::MraFilesQueueAccept(HANDLE hQueue, DWORD dwIDRequest, LPCWSTR lpwszPath, size_t dwPathSize)
-{
- if (!hQueue || !lpwszPath || !dwPathSize)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
-
- mir_cslock l(pmrafqFilesQueue->cs);
- DWORD dwRetErrorCode = MraFilesQueueItemFindByID(hQueue, dwIDRequest, &dat);
- if (dwRetErrorCode == NO_ERROR) {
- MRA_FILES_THREADPROC_PARAMS *pmftpp = (MRA_FILES_THREADPROC_PARAMS*)mir_calloc(sizeof(MRA_FILES_THREADPROC_PARAMS));
- dat->lpwszPath = (LPWSTR)mir_calloc(((dwPathSize+2)*sizeof(WCHAR)));
- dat->dwPathSize = dwPathSize;
- memcpy(dat->lpwszPath, lpwszPath, (dwPathSize*sizeof(WCHAR)));
-
- if ((*(WCHAR*)(dat->lpwszPath + (dat->dwPathSize - 1))) != '\\') {// add slash at the end if needed
- (*(WCHAR*)(dat->lpwszPath + dat->dwPathSize)) = '\\';
- dat->dwPathSize++;
- (*(WCHAR*)(dat->lpwszPath + dat->dwPathSize)) = 0;
- }
-
- pmftpp->hFilesQueueHandle = hFilesQueueHandle;
- pmftpp->dat = dat;
-
- dat->hThread = ForkThreadEx(&CMraProto::MraFilesQueueRecvThreadProc, pmftpp, nullptr);
- }
- return dwRetErrorCode;
-}
-
-DWORD CMraProto::MraFilesQueueCancel(HANDLE hQueue, DWORD dwIDRequest, BOOL bSendDecline)
-{
- if (!hQueue)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
-
- mir_cslock l(pmrafqFilesQueue->cs);
- DWORD dwRetErrorCode = MraFilesQueueItemFindByID(hQueue, dwIDRequest, &dat);
- if (dwRetErrorCode == NO_ERROR) { //***deb closesocket, send message to thread
- InterlockedExchange((volatile LONG*)&dat->bIsWorking, FALSE);
-
- if (bSendDecline) {
- CMStringA szEmail;
- if (mraGetStringA(dat->hContact, "e-mail", szEmail))
- MraFileTransferAck(FILE_TRANSFER_STATUS_DECLINE, szEmail, dwIDRequest, CMStringA());
- }
-
- MraMrimProxyCloseConnection(dat->hMraMrimProxyData);
-
- NETLIB_CLOSEHANDLE(dat->hListen);
- NETLIB_CLOSEHANDLE(dat->hConnection);
-
- SetEvent(dat->hWaitHandle);
-
- if (dat->hThread == nullptr)
- MraFilesQueueItemFree(dat);
- }
- return dwRetErrorCode;
-}
-
-DWORD CMraProto::MraFilesQueueStartMrimProxy(HANDLE hQueue, DWORD dwIDRequest)
-{
- if (!hQueue || !getByte("FileSendEnableMRIMProxyCons", MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS))
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
-
- mir_cslock l(pmrafqFilesQueue->cs);
- if (!MraFilesQueueItemFindByID(hQueue, dwIDRequest, &dat))
- if (dat->bSending == FALSE)
- SetEvent(dat->hWaitHandle);// cancel wait incomming connection
-
- return 0;
-}
-
-DWORD MraFilesQueueFree(HANDLE hQueue, DWORD dwIDRequest)
-{
- if (!hQueue)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
- LIST_MT_ITERATOR lmtiIterator;
-
- mir_cslock l(pmrafqFilesQueue->cs);
- ListMTIteratorMoveFirst(pmrafqFilesQueue, &lmtiIterator);
- do {
- if (ListMTIteratorGet(&lmtiIterator, nullptr, (LPVOID*)&dat) == NO_ERROR)
- if (dat->dwIDRequest == dwIDRequest) {
- MraFilesQueueItemFree(dat);
- return 0;
- }
- }
- while (ListMTIteratorMoveNext(&lmtiIterator));
-
- return ERROR_NOT_FOUND;
-}
-
-DWORD CMraProto::MraFilesQueueSendMirror(HANDLE hQueue, DWORD dwIDRequest, const CMStringA &szAddresses)
-{
- if (!hQueue)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat;
-
- mir_cslock l(pmrafqFilesQueue->cs);
- DWORD dwRetErrorCode = MraFilesQueueItemFindByID(hQueue, dwIDRequest, &dat);
- if (dwRetErrorCode == NO_ERROR) {
- MraAddrListGetFromBuff(szAddresses, &dat->malAddrList);
- MraAddrListStoreToContact(dat->hContact, &dat->malAddrList);
-
- dat->hConnection = nullptr;
- SetEvent(dat->hWaitHandle);
- }
- return dwRetErrorCode;
-}
-
-bool CMraProto::MraFilesQueueHandCheck(HNETLIBCONN hConnection, MRA_FILES_QUEUE_ITEM *dat)
-{
- if (hConnection && dat) {
- BYTE btBuff[((MAX_EMAIL_LEN * 2) + (sizeof(MRA_FT_HELLO)* 2) + 8)] = { 0 };
- size_t dwBuffSize;
-
- CMStringA szEmail, szEmailMy;
- if (!mraGetStringA(NULL, "e-mail", szEmailMy) || !mraGetStringA(dat->hContact, "e-mail", szEmail))
- return false;
-
- szEmailMy.MakeLower();
- szEmail.MakeLower();
-
- if (dat->bSending == FALSE) {
- // receiving
- dwBuffSize = mir_snprintf((LPSTR)btBuff, _countof(btBuff), "%s %s", MRA_FT_HELLO, szEmailMy.c_str()) + 1;
- if (dwBuffSize == (size_t)Netlib_Send(hConnection, (LPSTR)btBuff, (int)dwBuffSize, 0)) {
- // my email sended
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, (HANDLE)dat->dwIDRequest, 0);
- dwBuffSize = Netlib_Recv(hConnection, (LPSTR)btBuff, sizeof(btBuff), 0);
- if ((szEmail.GetLength() + sizeof(MRA_FT_HELLO)+1) == dwBuffSize) {
- // email received
- mir_snprintf(((LPSTR)btBuff + dwBuffSize), (_countof(btBuff) - dwBuffSize), "%s %s", MRA_FT_HELLO, szEmail.c_str());
- if (!_memicmp(btBuff, btBuff + dwBuffSize, dwBuffSize))
- return true;
- }
- }
- }
- else {// sending
- dwBuffSize = Netlib_Recv(hConnection, (LPSTR)btBuff, sizeof(btBuff), 0);
- if ((szEmail.GetLength() + sizeof(MRA_FT_HELLO)+1) == dwBuffSize) {
- // email received
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, (HANDLE)dat->dwIDRequest, 0);
- mir_snprintf(((LPSTR)btBuff + dwBuffSize), (_countof(btBuff) - dwBuffSize), "%s %s", MRA_FT_HELLO, szEmail.c_str());
- if (!_memicmp(btBuff, btBuff + dwBuffSize, dwBuffSize)) {
- // email verified
- dwBuffSize = (mir_snprintf((LPSTR)btBuff, _countof(btBuff), "%s %s", MRA_FT_HELLO, szEmailMy.c_str()) + 1);
- if (dwBuffSize == (size_t)Netlib_Send(hConnection, (LPSTR)btBuff, (int)dwBuffSize, 0))
- return true;
- }
- }
- }
- }
- return false;
-}
-
-HANDLE CMraProto::MraFilesQueueConnectOut(MRA_FILES_QUEUE_ITEM *dat)
-{
- if (!dat)
- return nullptr;
-
- if (getByte("FileSendEnableDirectConn", MRA_DEF_FS_ENABLE_DIRECT_CONN) && InterlockedExchangeAdd((volatile LONG*)&dat->bIsWorking, 0) && ((dat->bSending == FALSE && getByte("FileSendNoOutConnOnRcv", MRA_DEF_FS_NO_OUT_CONN_ON_RCV) == FALSE) || (dat->bSending == TRUE && getByte("FileSendNoOutConnOnSend", MRA_DEF_FS_NO_OUT_CONN_ON_SEND) == FALSE))) {
- BOOL bFiltering = FALSE, bIsHTTPSProxyUsed = IsHTTPSProxyUsed(m_hNetlibUser);
- DWORD dwLocalPort = 0, dwConnectReTryCount, dwCurConnectReTryCount;
- size_t dwAddrCount = 0;
- NETLIBOPENCONNECTION nloc = { 0 };
-
- if (getByte("FileSendIgnoryAdditionalPorts", MRA_DEF_FS_IGNORY_ADDITIONAL_PORTS) || bIsHTTPSProxyUsed) {// фильтруем порты для одного IP, вместо 3 будем коннектится только к одному
- if (bIsHTTPSProxyUsed)
- dwLocalPort = MRA_SERVER_PORT_HTTPS;
- else if ((dwLocalPort = getWord("ServerPort", MRA_DEFAULT_SERVER_PORT)) == MRA_SERVER_PORT_STANDART_NLB)
- dwLocalPort = MRA_SERVER_PORT_STANDART;
-
- for (size_t i = 0; i < dat->malAddrList.dwAddrCount; i++) {
- if (dwLocalPort == dat->malAddrList.pMailAddress[i].dwPort) {
- bFiltering = TRUE;
- dwAddrCount++;
- }
- }
- }
-
- if (bFiltering == FALSE)
- dwAddrCount = dat->malAddrList.dwAddrCount;
-
- if (dwAddrCount) {
- dat->hConnection = nullptr;
- dwConnectReTryCount = getDword("ConnectReTryCountFileSend", MRA_DEFAULT_CONN_RETRY_COUNT_FILES);
- nloc.cbSize = sizeof(nloc);
- nloc.flags = NLOCF_V2;
- nloc.timeout = getDword("TimeOutConnectFileSend", (int)((MRA_TIMEOUT_DIRECT_CONN - 1) / (dwAddrCount*dwConnectReTryCount)));// -1 сек чтобы был запас
- if (nloc.timeout < MRA_TIMEOUT_CONN_MIN) nloc.timeout = MRA_TIMEOUT_CONN_MIN;
- if (nloc.timeout > MRA_TIMEOUT_CONN_MAX) nloc.timeout = MRA_TIMEOUT_CONN_MAX;
-
- // Set up the sockaddr structure
- for (size_t i = 0; i < dat->malAddrList.dwAddrCount; i++) {
- if (dwLocalPort == dat->malAddrList.pMailAddress[i].dwPort || bFiltering == FALSE) {
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)dat->dwIDRequest, 0);
-
- nloc.szHost = inet_ntoa((*((in_addr*)&dat->malAddrList.pMailAddress[i].dwAddr)));
- nloc.wPort = (WORD)dat->malAddrList.pMailAddress[i].dwPort;
-
- dwCurConnectReTryCount = dwConnectReTryCount;
- do {
- dat->hConnection = Netlib_OpenConnection(m_hNetlibUser, &nloc);
- }
- while (--dwCurConnectReTryCount && dat->hConnection == nullptr);
-
- if (dat->hConnection) {
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- if (MraFilesQueueHandCheck(dat->hConnection, dat)) {
- // связь установленная с тем кем нужно
- setDword(dat->hContact, "OldIP", getDword(dat->hContact, "IP", 0));
- setDword(dat->hContact, "IP", ntohl(dat->malAddrList.pMailAddress[i].dwAddr));
- break;
- }
- else // кажется не туда подключились :)
- NETLIB_CLOSEHANDLE(dat->hConnection);
- }
- }
- }
- }
- }
- return dat->hConnection;
-}
-
-LPWSTR GetFileNameFromFullPathW(LPWSTR lpwszFullPath, size_t dwFullPathSize)
-{
- LPWSTR lpwszFileName = lpwszFullPath, lpwszCurPos;
-
- lpwszCurPos = (lpwszFullPath + dwFullPathSize);
- for (; lpwszCurPos > lpwszFullPath; lpwszCurPos--) {
- if ((*lpwszCurPos) == '\\') {
- lpwszFileName = (lpwszCurPos + 1);
- break;
- }
- }
- return lpwszFileName;
-}
-
-HANDLE CMraProto::MraFilesQueueConnectIn(MRA_FILES_QUEUE_ITEM *dat)
-{
- if (!dat)
- return nullptr;
- if (!InterlockedExchangeAdd((volatile LONG*)&dat->bIsWorking, 0))
- return nullptr;
-
- CMStringA szEmail;
- if (mraGetStringA(dat->hContact, "e-mail", szEmail)) {
- CHAR szAddrList[2048] = { 0 };
- size_t dwAddrListSize;
-
- // копируем адреса в соответствии с правилами и начинаем слушать порт
- if (getByte("FileSendEnableDirectConn", MRA_DEF_FS_ENABLE_DIRECT_CONN)) {
- NETLIBBIND nlbBind = {};
- nlbBind.pfnNewConnectionV2 = MraFilesQueueConnectionReceived;
- nlbBind.wPort = 0;
- nlbBind.pExtra = (LPVOID)dat;
-
- dat->hListen = Netlib_BindPort(m_hNetlibUser, &nlbBind);
- if (dat->hListen) {
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_LISTENING, (HANDLE)dat->dwIDRequest, 0);
- dwAddrListSize = MraFilesQueueGetLocalAddressesList(szAddrList, sizeof(szAddrList), nlbBind.wPort);
- }
- // не смогли слушать порт, хз почему.
- else {
- ShowFormattedErrorMessage(L"Files exchange: cant create listen soscket, will try connect to remonte host. Error", GetLastError());
-
- //dwAddrListSize = 0;
- memcpy(szAddrList, MRA_FILES_NULL_ADDRR, sizeof(MRA_FILES_NULL_ADDRR));
- dwAddrListSize = (sizeof(MRA_FILES_NULL_ADDRR)-1);
- }
- }
- // подставляем ложный адрес, чтобы точно не подключились и не слушаем порт
- else {
- memcpy(szAddrList, MRA_FILES_NULL_ADDRR, sizeof(MRA_FILES_NULL_ADDRR));
- dwAddrListSize = (sizeof(MRA_FILES_NULL_ADDRR)-1);
- }
-
- if (dwAddrListSize) {
- dat->hWaitHandle = CreateEvent(nullptr, TRUE, FALSE, nullptr);
- if (dat->bSending == FALSE) // запрашиваем зеркальное соединение, тк сами подключится не смогли
- MraFileTransferAck(FILE_TRANSFER_MIRROR, szEmail, dat->dwIDRequest, szAddrList);
- else { // здесь отправляем запрос на передачу(установление соединения)
- // создаём текстовый список файлов для отправки другой стороне
- LPWSTR lpwszFiles, lpwszCurPos;
- size_t dwFilesSize;
-
- dwFilesSize = ((MAX_PATH * 2)*dat->dwFilesCount);
- lpwszFiles = (LPWSTR)mir_calloc((dwFilesSize*sizeof(WCHAR)));
- if (lpwszFiles) {
- lpwszCurPos = lpwszFiles;
- for (size_t i = 0; i < dat->dwFilesCount; i++) {
- MRA_FILES_QUEUE_FILE &p = dat->pmfqfFiles[i];
- lpwszCurPos += mir_snwprintf(lpwszCurPos, (dwFilesSize - ((size_t)lpwszCurPos - (size_t)lpwszFiles)), L"%s;%I64u;",
- GetFileNameFromFullPathW(p.lpwszName, p.dwNameLen), p.dwSize);
- }
- dwFilesSize = (lpwszCurPos - lpwszFiles);// size in WCHARs
-
- if (dat->hMraMrimProxyData) {
- // устанавливаем данные для майловской прокси, если она разрешена
- CMStringA lpszFiles = lpwszFiles;
- MraMrimProxySetData(dat->hMraMrimProxyData, szEmail, dat->dwIDRequest, MRIM_PROXY_TYPE_FILES, lpszFiles, "", nullptr);
- }
- MraFileTransfer(szEmail, dat->dwIDRequest, dat->dwFilesTotalSize, lpwszFiles, szAddrList);
-
- mir_free(lpwszFiles);
- }
- }
- WaitForSingleObjectEx(dat->hWaitHandle, INFINITE, FALSE);
- CloseHandle(dat->hWaitHandle);
- dat->hWaitHandle = nullptr;
- }
- }
- return dat->hConnection;
-}
-
-// This function is called from the Netlib when someone is connecting to
-// one of our incomming DC ports
-void MraFilesQueueConnectionReceived(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra)
-{
- if (pExtra) {
- MRA_FILES_QUEUE_ITEM *dat = (MRA_FILES_QUEUE_ITEM*)pExtra;
-
- ProtoBroadcastAck(dat->ppro->m_szModuleName, dat->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- if (dat->ppro->MraFilesQueueHandCheck(hNewConnection, dat)) { // связь установленная с тем кем нужно
- dat->hConnection = hNewConnection;
- ProtoBroadcastAck(dat->ppro->m_szModuleName, dat->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- dat->ppro->setDword(dat->hContact, "OldIP", dat->ppro->getDword(dat->hContact, "IP", 0));
- dat->ppro->setDword(dat->hContact, "IP", dwRemoteIP);
- SetEvent(dat->hWaitHandle);
- }
- else {// кажется кто то не туда подключилися :)
- ProtoBroadcastAck(dat->ppro->m_szModuleName, dat->hContact, ACKTYPE_FILE, ACKRESULT_LISTENING, (HANDLE)dat->dwIDRequest, 0);
- Netlib_CloseHandle(hNewConnection);
- }
- }
- else Netlib_CloseHandle(hNewConnection);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Receive files
-
-DWORD CMraProto::MraFilesQueueAddReceive(HANDLE hQueue, DWORD dwFlags, MCONTACT hContact, DWORD dwIDRequest, const CMStringW &lpwszFiles, const CMStringA &szAddresses)
-{
- if (!hQueue || !dwIDRequest)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat = (MRA_FILES_QUEUE_ITEM*)mir_calloc(sizeof(MRA_FILES_QUEUE_ITEM)+sizeof(LPSTR)+64);
- if (!dat)
- return GetLastError();
-
- WCHAR szBuff[MAX_PATH];
- size_t dwMemSize, dwAllocatedCount, dwFileNameTotalSize;
-
- //dat->lmtListMTItem;
- dat->ppro = this;
- dat->bIsWorking = TRUE;
- dat->dwSendTime = GetTickCount();
- dat->dwIDRequest = dwIDRequest;
- dat->dwFlags = dwFlags;
- dat->hContact = hContact;
- if (getByte("FileSendEnableMRIMProxyCons", MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS))
- dat->hMraMrimProxyData = MraMrimProxyCreate();
-
- dwFileNameTotalSize = 0;
- dwAllocatedCount = ALLOCATED_COUNT;
- dat->dwFilesCount = 0;
- dat->dwFilesTotalSize = 0;
- dat->pmfqfFiles = (MRA_FILES_QUEUE_FILE*)mir_calloc((sizeof(MRA_FILES_QUEUE_FILE)*dwAllocatedCount));
-
- int iStart = 0;
- while (TRUE) {
- CMStringW wszCurrFile = lpwszFiles.Tokenize(L";", iStart);
- if (iStart == -1)
- break;
-
- CMStringW wszCurrSize = lpwszFiles.Tokenize(L";", iStart);
- if (iStart == -1)
- break;
-
- if (dat->dwFilesCount == dwAllocatedCount) {
- dwAllocatedCount *= 2;
- dat->pmfqfFiles = (MRA_FILES_QUEUE_FILE*)mir_realloc(dat->pmfqfFiles, (sizeof(MRA_FILES_QUEUE_FILE)*dwAllocatedCount));
- }
-
- MRA_FILES_QUEUE_FILE &p = dat->pmfqfFiles[dat->dwFilesCount];
- p.lpwszName = mir_wstrdup(wszCurrFile);
- p.dwNameLen = mir_wstrlen(p.lpwszName);
- p.dwSize = _wtoi(wszCurrSize);
- dat->dwFilesTotalSize += p.dwSize;
- dwFileNameTotalSize += p.dwNameLen * sizeof(wchar_t);
-
- dat->dwFilesCount++;
- }
- dat->pmfqfFiles = (MRA_FILES_QUEUE_FILE*)mir_realloc(dat->pmfqfFiles, (sizeof(MRA_FILES_QUEUE_FILE)*(dat->dwFilesCount + 4)));
-
- dwMemSize = (((dat->dwFilesCount + 4) * 64) + (dwFileNameTotalSize*sizeof(WCHAR)) + (szAddresses.GetLength()*sizeof(WCHAR)) + 128);
- dat->pwszFilesList = (LPWSTR)mir_calloc(dwMemSize);
- dat->pwszDescription = (LPWSTR)mir_calloc(dwMemSize);
-
- LPWSTR lpwszDelimiter = dat->pwszFilesList;
- LPWSTR lpwszCurrentItem = dat->pwszDescription;
- StrFormatByteSizeW(dat->dwFilesTotalSize, szBuff, _countof(szBuff));
- lpwszCurrentItem += mir_snwprintf(lpwszCurrentItem, ((dwMemSize - ((size_t)lpwszCurrentItem - (size_t)dat->pwszDescription)) / sizeof(WCHAR)), L"%I64u Files (%s)\r\n", dat->dwFilesCount, szBuff);
-
- // description + filesnames
- for (size_t i = 0; i < dat->dwFilesCount; i++) {
- lpwszDelimiter += mir_snwprintf(lpwszDelimiter, ((dwMemSize - ((size_t)lpwszDelimiter - (size_t)dat->pwszFilesList)) / sizeof(WCHAR)), L"%s", dat->pmfqfFiles[i].lpwszName);
- StrFormatByteSizeW(dat->pmfqfFiles[i].dwSize, szBuff, _countof(szBuff));
- lpwszCurrentItem += mir_snwprintf(lpwszCurrentItem, ((dwMemSize - ((size_t)lpwszCurrentItem - (size_t)dat->pwszDescription)) / sizeof(WCHAR)), L"%s - %s\r\n", dat->pmfqfFiles[i].lpwszName, szBuff);
- }
-
- lpwszCurrentItem += MultiByteToWideChar(MRA_CODE_PAGE, 0, szAddresses, (int)szAddresses.GetLength(), lpwszCurrentItem, (int)((dwMemSize - ((size_t)lpwszCurrentItem - (size_t)dat->pwszDescription)) / sizeof(WCHAR)));
- *lpwszCurrentItem = 0;
-
- MraAddrListGetFromBuff(szAddresses, &dat->malAddrList);
- MraAddrListStoreToContact(dat->hContact, &dat->malAddrList);
- {
- mir_cslock l(pmrafqFilesQueue->cs);
- ListMTItemAdd(pmrafqFilesQueue, dat, dat);
- }
-
- // Send chain event
- PROTORECVFILE prf;
- prf.dwFlags = PRFF_UNICODE;
- prf.timestamp = _time32(nullptr);
- prf.descr.w = dat->pwszDescription;
- prf.fileCount = 1;
- prf.files.w = &dat->pwszFilesList;
- prf.lParam = dwIDRequest;
- ProtoChainRecvFile(hContact, &prf);
- return NO_ERROR;
-}
-
-void CMraProto::MraFilesQueueRecvThreadProc(LPVOID lpParameter)
-{
- DWORD dwRetErrorCode = NO_ERROR;
-
- Thread_SetName("MRA: FilesQueueRecv");
-
- if (lpParameter) {
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->hFilesQueueHandle;
- MRA_FILES_QUEUE_ITEM *dat = ((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->dat;
-
- WCHAR wszFileName[MAX_FILEPATH] = { 0 };
- WCHAR szErrorText[2048];
- BYTE btBuff[BUFF_SIZE_RCV];
- BOOL bContinue, bFailed, bOK, bConnected;
- DWORD dwReceived, dwUpdateTimeNext, dwUpdateTimeCur;
- HANDLE hFile;
- size_t i, dwBuffSizeUsed;
- LARGE_INTEGER liFileSize;
- NETLIBSELECT nls = { 0 };
- PROTOFILETRANSFERSTATUS pfts = {};
-
- mir_free(lpParameter);
-
- bFailed = TRUE;
- bConnected = FALSE;
- pfts.hContact = dat->hContact;
- pfts.flags = (PFTS_RECEIVING | PFTS_UNICODE);// pfts.sending = dat->bSending; //true if sending, false if receiving
- //pfts.files;
- pfts.totalFiles = dat->dwFilesCount;
- //pfts.currentFileNumber = 0;
- pfts.totalBytes = dat->dwFilesTotalSize;
- //pfts.totalProgress = 0;
- pfts.szWorkingDir.w = dat->lpwszPath;
- //pfts.currentFile;
- //pfts.currentFileSize;
- //pfts.currentFileProgress;
- //pfts.currentFileTime; //as seconds since 1970
-
- if (MraFilesQueueConnectOut(dat)) {
- bConnected = TRUE;
- }
- else {
- if (MraFilesQueueConnectIn(dat)) {
- bConnected = TRUE;
- }
- else {
- if (InterlockedExchangeAdd((volatile LONG*)&dat->bIsWorking, 0)) {
- ProtoBroadcastAck(dat->hContact, ACKRESULT_CONNECTPROXY, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- if (MraMrimProxyConnect(dat->hMraMrimProxyData, &dat->hConnection) == NO_ERROR) {// подключились к прокси, проверяем та ли сессия (ещё раз, на этот раз сами)
- if (MraFilesQueueHandCheck(dat->hConnection, dat)) {// связь установленная с тем кем нужно// dat->bSending
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- bConnected = TRUE;
- }
- }
- }
- }
- }
-
- if (bConnected) {// email verified
- bFailed = FALSE;
- for (i = 0; i < dat->dwFilesCount; i++) {// receiving files
- pfts.currentFileNumber = (int)i;
- pfts.szCurrentFile.w = wszFileName;
- pfts.currentFileSize = dat->pmfqfFiles[i].dwSize;
- pfts.currentFileProgress = 0;
- //pfts.currentFileTime; //as seconds since 1970
-
- if ((dat->dwPathSize + dat->pmfqfFiles[i].dwNameLen) < _countof(wszFileName)) {
- memcpy(wszFileName, dat->lpwszPath, (dat->dwPathSize*sizeof(WCHAR)));
- memcpy((wszFileName + dat->dwPathSize), dat->pmfqfFiles[i].lpwszName, ((dat->pmfqfFiles[i].dwNameLen + 1)*sizeof(WCHAR)));
- wszFileName[dat->dwPathSize + dat->pmfqfFiles[i].dwNameLen] = 0;
- }
- else {
- dwRetErrorCode = ERROR_BAD_PATHNAME;
- ShowFormattedErrorMessage(L"Receive files: error", dwRetErrorCode);
- bFailed = TRUE;
- break;
- }
-
- //***deb add
- //dwBuffSizeUsed = ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)dat->dwIDRequest, (LPARAM)&pfts);
-
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, (HANDLE)dat->dwIDRequest, 0);
-
- //dwBuffSizeUsed = (mir_snprintf((LPSTR)btBuff, _countof(btBuff), "%s %S", MRA_FT_GET_FILE, dat->pmfqfFiles[i].lpwszName)+1);
- memcpy(btBuff, MRA_FT_GET_FILE, sizeof(MRA_FT_GET_FILE));
- btBuff[(sizeof(MRA_FT_GET_FILE)-1)] = ' ';
- dwBuffSizeUsed = sizeof(MRA_FT_GET_FILE) + WideCharToMultiByte(MRA_CODE_PAGE, 0, dat->pmfqfFiles[i].lpwszName, (int)dat->pmfqfFiles[i].dwNameLen, (LPSTR)(btBuff + sizeof(MRA_FT_GET_FILE)), (int)(_countof(btBuff) - sizeof(MRA_FT_GET_FILE)), nullptr, nullptr);
- btBuff[dwBuffSizeUsed] = 0;
- dwBuffSizeUsed++;
-
- if (dwBuffSizeUsed == (size_t)Netlib_Send(dat->hConnection, (LPSTR)btBuff, (int)dwBuffSizeUsed, 0)) {// file request sended
- hFile = CreateFileW(wszFileName, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (hFile != INVALID_HANDLE_VALUE) {// file opened/created, pre allocating disk space, for best perfomance
- bOK = FALSE;
-
- liFileSize.QuadPart = (LONGLONG)dat->pmfqfFiles[i].dwSize;
- if (SetFilePointerEx(hFile, liFileSize, nullptr, FILE_BEGIN))
- if (SetEndOfFile(hFile)) {
- liFileSize.QuadPart = 0;
- bOK = SetFilePointerEx(hFile, liFileSize, nullptr, FILE_BEGIN);
- }
-
- if (bOK) {// disk space pre allocated
- bOK = FALSE;
- bContinue = TRUE;
- dwUpdateTimeNext = GetTickCount();
- nls.dwTimeout = (1000 * getDword("TimeOutReceiveFileData", MRA_DEF_FS_TIMEOUT_RECV));
- nls.hReadConns[0] = dat->hConnection;
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)dat->dwIDRequest, (LPARAM)&pfts);
-
- while (bContinue) {
- switch (Netlib_Select(&nls)) {
- case SOCKET_ERROR:
- case 0:// Time out
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Receive files: error on receive file data", dwRetErrorCode);
- bContinue = FALSE;
- break;
- case 1:
- dwReceived = Netlib_Recv(dat->hConnection, (LPSTR)&btBuff, _countof(btBuff), 0);
- if (dwReceived == 0 || dwReceived == SOCKET_ERROR) {
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Receive files: error on receive file data", dwRetErrorCode);
- bContinue = FALSE;
- }
- else {
- if (WriteFile(hFile, (LPVOID)&btBuff, dwReceived, &dwReceived, nullptr)) {
- pfts.currentFileProgress += dwReceived;
- pfts.totalProgress += dwReceived;
-
- // progress updates
- dwUpdateTimeCur = GetTickCount();
- if (dwUpdateTimeNext <= dwUpdateTimeCur || pfts.currentFileProgress >= dat->pmfqfFiles[i].dwSize) {// we update it
- dwUpdateTimeNext = dwUpdateTimeCur + MRA_FILES_QUEUE_PROGRESS_INTERVAL;
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)dat->dwIDRequest, (LPARAM)&pfts);
-
- if (pfts.currentFileProgress >= dat->pmfqfFiles[i].dwSize) {// file received
- bOK = TRUE;
- bContinue = FALSE;
- }
- }
- }
- else {// err on write file
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Receive files: cant write file data, error", dwRetErrorCode);
- bContinue = FALSE;
- }
- }
- break;
- }
- }// end while
- }
- else {// err allocating file disk space
- dwRetErrorCode = GetLastError();
- mir_snwprintf(szErrorText, TranslateT("Receive files: can't allocate disk space for file, size %lu bytes, error"), dat->pmfqfFiles[i].dwSize);
- ShowFormattedErrorMessage(szErrorText, dwRetErrorCode);
- }
- CloseHandle(hFile);
-
- if (bOK == FALSE) {// file recv failed
- DeleteFileW(wszFileName);
- bFailed = TRUE;
- break;
- }
- }
- else {// err on open file
- dwRetErrorCode = GetLastError();
- mir_snwprintf(szErrorText, TranslateT("Receive files: can't open file %s, error"), wszFileName);
- ShowFormattedErrorMessage(szErrorText, dwRetErrorCode);
- bFailed = TRUE;
- break;
- }
- }
- else {// err on send request for file
- dwRetErrorCode = GetLastError();
- mir_snwprintf(szErrorText, TranslateT("Receive files: request for file %s not sent, error"), dat->pmfqfFiles[i].lpwszName);
- ShowFormattedErrorMessage(szErrorText, NO_ERROR);
- bFailed = TRUE;
- break;
- }
- }// end for
-
- NETLIB_CLOSEHANDLE(dat->hConnection);
- }
-
- if (bFailed) {
- CMStringA szEmail;
- if (mraGetStringA(dat->hContact, "e-mail", szEmail))
- MraFileTransferAck(FILE_TRANSFER_STATUS_ERROR, szEmail, dat->dwIDRequest, CMStringA());
-
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)dat->dwIDRequest, 0);
- }
- else ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)dat->dwIDRequest, 0);
-
- mir_cslock l(pmrafqFilesQueue->cs);
- MraFilesQueueItemFree(dat);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Send files
-
-DWORD CMraProto::MraFilesQueueAddSend(HANDLE hQueue, DWORD dwFlags, MCONTACT hContact, LPWSTR *plpwszFiles, size_t dwFilesCount, DWORD *pdwIDRequest)
-{
- if (!hQueue)
- return ERROR_INVALID_HANDLE;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)hQueue;
- MRA_FILES_QUEUE_ITEM *dat = (MRA_FILES_QUEUE_ITEM*)mir_calloc(sizeof(MRA_FILES_QUEUE_ITEM)+sizeof(LPSTR)+64);
- if (!dat)
- return GetLastError();
-
- ULARGE_INTEGER uliFileSize;
- WIN32_FILE_ATTRIBUTE_DATA wfad;
-
- dat->ppro = this;
- dat->bIsWorking = TRUE;
- dat->dwSendTime = GetTickCount();
- dat->dwIDRequest = InterlockedIncrement((LONG volatile*)&dwCMDNum);// уникальный, рандомный идентификатор
- dat->dwFlags = dwFlags;
- dat->hContact = hContact;
- if (getByte("FileSendEnableMRIMProxyCons", MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS)) dat->hMraMrimProxyData = MraMrimProxyCreate();
- dat->dwFilesCount = dwFilesCount;
- dat->pmfqfFiles = (MRA_FILES_QUEUE_FILE*)mir_calloc((sizeof(MRA_FILES_QUEUE_FILE)*(dat->dwFilesCount + 1)));
- dat->dwFilesTotalSize = 0;
-
- for (size_t i = 0; i < dat->dwFilesCount; i++) {
- MRA_FILES_QUEUE_FILE &p = dat->pmfqfFiles[i];
- if (GetFileAttributesExW(plpwszFiles[i], GetFileExInfoStandard, &wfad)) {
- uliFileSize.LowPart = wfad.nFileSizeLow;
- uliFileSize.HighPart = wfad.nFileSizeHigh;
- p.dwSize = uliFileSize.QuadPart;
- dat->dwFilesTotalSize += uliFileSize.QuadPart;
- }
- else p.dwSize = 0;
-
- p.dwNameLen = mir_wstrlen(plpwszFiles[i]);
- p.lpwszName = mir_wstrdup(plpwszFiles[i]);
- }
-
- dat->bSending = TRUE;
- if (pdwIDRequest) *pdwIDRequest = dat->dwIDRequest;
-
- {
- mir_cslock l(pmrafqFilesQueue->cs);
- ListMTItemAdd(pmrafqFilesQueue, dat, dat);
- }
- MRA_FILES_THREADPROC_PARAMS *pmftpp = (MRA_FILES_THREADPROC_PARAMS*)mir_calloc(sizeof(MRA_FILES_THREADPROC_PARAMS));
- pmftpp->hFilesQueueHandle = hQueue;
- pmftpp->dat = dat;
- dat->hThread = ForkThreadEx(&CMraProto::MraFilesQueueSendThreadProc, pmftpp, nullptr);
-
- return NO_ERROR;
-}
-
-void CMraProto::MraFilesQueueSendThreadProc(LPVOID lpParameter)
-{
- DWORD dwRetErrorCode = NO_ERROR;
-
- Thread_SetName("MRA: FilesQueueSend");
-
- if (!lpParameter)
- return;
-
- MRA_FILES_QUEUE *pmrafqFilesQueue = (MRA_FILES_QUEUE*)((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->hFilesQueueHandle;
- MRA_FILES_QUEUE_ITEM *dat = ((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->dat;
- mir_free(lpParameter);
-
- CHAR szFileName[MAX_FILEPATH] = { 0 };
- WCHAR szErrorText[2048];
- BYTE btBuff[BUFF_SIZE_RCV];
- BOOL bFailed = TRUE, bOK, bConnected = FALSE;
- DWORD dwReceived, dwSendBlockSize, dwUpdateTimeNext, dwUpdateTimeCur;
- size_t i, j, dwBuffSizeUsed = 0;
- LPWSTR lpwszFileName;
-
- PROTOFILETRANSFERSTATUS pfts = {};
- pfts.hContact = dat->hContact;
- pfts.flags = (PFTS_SENDING | PFTS_UNICODE);// pfts.sending = dat->bSending; //true if sending, false if receiving
- pfts.totalFiles = dat->dwFilesCount;
- pfts.totalBytes = dat->dwFilesTotalSize;
- pfts.szWorkingDir.w = dat->lpwszPath;
-
- dwSendBlockSize = getDword("FileSendBlockSize", MRA_DEFAULT_FILE_SEND_BLOCK_SIZE);
- if (dwSendBlockSize > _countof(btBuff)) dwSendBlockSize = _countof(btBuff);
- if (dwSendBlockSize < 512) dwSendBlockSize = MRA_DEFAULT_FILE_SEND_BLOCK_SIZE;
-
- if (MraFilesQueueConnectIn(dat))
- bConnected = TRUE;
- else if (MraFilesQueueConnectOut(dat))
- bConnected = TRUE;
- else {
- if (InterlockedExchangeAdd((volatile LONG*)&dat->bIsWorking, 0)) {
- ProtoBroadcastAck(dat->hContact, ACKRESULT_CONNECTPROXY, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- if (MraMrimProxyConnect(dat->hMraMrimProxyData, &dat->hConnection) == NO_ERROR) {
- // подключились к прокси, проверяем та ли сессия (ещё раз, на этот раз сами)
- if (MraFilesQueueHandCheck(dat->hConnection, dat)) {
- // связь установленная с тем кем нужно// dat->bSending
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)dat->dwIDRequest, 0);
- bConnected = TRUE;
- }
- }
- }
- }
-
- if (bConnected) { // email verified
- bFailed = FALSE;
- for (i = 0; i < dat->dwFilesCount; i++) { // sending files
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, (HANDLE)dat->dwIDRequest, 0);
-
- dwBuffSizeUsed = 0;
- while (TRUE) {
- dwReceived = Netlib_Recv(dat->hConnection, ((LPSTR)btBuff + dwBuffSizeUsed), (int)(_countof(btBuff) - dwBuffSizeUsed), 0);
- if (dwReceived == 0 || dwReceived == SOCKET_ERROR) { // err on receive file name to send
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Send files: file send request not received, error", dwRetErrorCode);
- bFailed = TRUE;
- break;
- }
- else {
- dwBuffSizeUsed += dwReceived;
- if (MemoryFindByte((dwBuffSizeUsed - dwReceived), btBuff, dwBuffSizeUsed, 0))
- break;
- }
- }// end while (file name passible received)*/
-
- if (bFailed)
- break;
-
- // ...received
- if (dwBuffSizeUsed > (sizeof(MRA_FT_GET_FILE)+1)) {// file name received
- if (!_memicmp(btBuff, MRA_FT_GET_FILE, sizeof(MRA_FT_GET_FILE)-1)) {
- // MRA_FT_GET_FILE verified
- bFailed = TRUE;
- for (j = 0; j < dat->dwFilesCount; j++) {
- lpwszFileName = GetFileNameFromFullPathW(dat->pmfqfFiles[j].lpwszName, dat->pmfqfFiles[j].dwNameLen);
- szFileName[WideCharToMultiByte(MRA_CODE_PAGE, 0, lpwszFileName, (int)(dat->pmfqfFiles[j].dwNameLen - (lpwszFileName - dat->pmfqfFiles[j].lpwszName)), szFileName, _countof(szFileName), nullptr, nullptr)] = 0;
-
- if (!_memicmp(btBuff + sizeof(MRA_FT_GET_FILE), szFileName, dwBuffSizeUsed - (sizeof(MRA_FT_GET_FILE)+1))) {
- bFailed = FALSE;
- break;
- }
- }
-
- if (bFailed == FALSE) {
- HANDLE hFile = CreateFileW(dat->pmfqfFiles[j].lpwszName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN), nullptr);
- if (hFile != INVALID_HANDLE_VALUE) {
- bOK = FALSE;
- dwUpdateTimeNext = GetTickCount();
- pfts.currentFileNumber = (int)i;
- pfts.szCurrentFile.w = dat->pmfqfFiles[j].lpwszName;
- pfts.currentFileSize = dat->pmfqfFiles[j].dwSize;
- pfts.currentFileProgress = 0;
- //pfts.currentFileTime; //as seconds since 1970
-
- WideCharToMultiByte(MRA_CODE_PAGE, 0, dat->pmfqfFiles[j].lpwszName, (int)dat->pmfqfFiles[j].dwNameLen, szFileName, _countof(szFileName), nullptr, nullptr);
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)dat->dwIDRequest, (LPARAM)&pfts);
-
- while (TRUE) { // read and sending
- if (ReadFile(hFile, btBuff, dwSendBlockSize, (DWORD*)&dwBuffSizeUsed, nullptr)) {
- dwReceived = Netlib_Send(dat->hConnection, (LPSTR)btBuff, (int)dwBuffSizeUsed, 0);
- if (dwBuffSizeUsed == dwReceived) {
- pfts.currentFileProgress += dwBuffSizeUsed;
- pfts.totalProgress += dwBuffSizeUsed;
-
- // progress updates
- dwUpdateTimeCur = GetTickCount();
- if (dwUpdateTimeNext <= dwUpdateTimeCur || pfts.currentFileProgress >= dat->pmfqfFiles[j].dwSize) { // we update it
- dwUpdateTimeNext = dwUpdateTimeCur + MRA_FILES_QUEUE_PROGRESS_INTERVAL;
-
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)dat->dwIDRequest, (LPARAM)&pfts);
-
- if (pfts.currentFileProgress >= dat->pmfqfFiles[j].dwSize) { // file received
- bOK = TRUE;
- break;
- }
- }
- }
- else { // err on send file data
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Send files: error on send file data", dwRetErrorCode);
- break;
- }
- }
- else {// read failure
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Send files: cant read file data, error", dwRetErrorCode);
- break;
- }
- }// end while
- CloseHandle(hFile);
-
- if (bOK == FALSE) { // file recv failed
- bFailed = TRUE;
- break;
- }
- }
- else { // err on open file
- dwRetErrorCode = GetLastError();
- mir_snwprintf(szErrorText, TranslateT("Send files: can't open file %s, error"), dat->pmfqfFiles[j].lpwszName);
- ShowFormattedErrorMessage(szErrorText, dwRetErrorCode);
- bFailed = TRUE;
- break;
- }
- }
- else {
- mir_snwprintf(szErrorText, TranslateT("Send files: requested file: %S - not found in send files list."), (((LPSTR)btBuff) + sizeof(MRA_FT_GET_FILE)));
- ShowFormattedErrorMessage(szErrorText, NO_ERROR);
- bFailed = TRUE;
- break;
- }
- }
- else { // err on receive, trash
- ShowFormattedErrorMessage(L"Send files: bad file send request - invalid header", NO_ERROR);
- bFailed = TRUE;
- break;
- }
- }
- else { // bad file name or trash
- ShowFormattedErrorMessage(L"Send files: bad file send request - to small packet", NO_ERROR);
- bFailed = TRUE;
- break;
- }
- }// end for
-
- NETLIB_CLOSEHANDLE(dat->hConnection);
- }
-
- if (bFailed) {
- CMStringA szEmail;
- if (mraGetStringA(dat->hContact, "e-mail", szEmail))
- MraFileTransferAck(FILE_TRANSFER_STATUS_ERROR, szEmail, dat->dwIDRequest, CMStringA());
-
- ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)dat->dwIDRequest, 0);
- }
- else ProtoBroadcastAck(dat->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)dat->dwIDRequest, 0);
-
- mir_cslock l(pmrafqFilesQueue->cs);
- MraFilesQueueItemFree(dat);
-}