From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MRA/MraFilesQueue.cpp | 1443 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1443 insertions(+) create mode 100644 protocols/MRA/MraFilesQueue.cpp (limited to 'protocols/MRA/MraFilesQueue.cpp') diff --git a/protocols/MRA/MraFilesQueue.cpp b/protocols/MRA/MraFilesQueue.cpp new file mode 100644 index 0000000000..3dd2055501 --- /dev/null +++ b/protocols/MRA/MraFilesQueue.cpp @@ -0,0 +1,1443 @@ +#include "Mra.h" +#include "MraFilesQueue.h" +#include "proto.h" + + + + +#define MRA_FT_HELLO "MRA_FT_HELLO" +#define MRA_FT_GET_FILE "MRA_FT_GET_FILE" + + + +typedef struct +{ + LIST_MT lmtListMT; + DWORD dwSendTimeOutInterval; +} MRA_FILES_QUEUE; + + + +struct MRA_FILES_QUEUE_FILE +{ + LPWSTR lpwszName; + SIZE_T dwNameLen; + DWORDLONG dwSize; +}; + + + + +typedef struct +{ + // internal + LIST_MT_ITEM lmtListMTItem; + BOOL bIsWorking; + DWORD dwSendTime; + // external + DWORD dwIDRequest; + DWORD dwFlags; + HANDLE 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; + HANDLE hConnection; + HANDLE hListen; + HANDLE hThread; + HANDLE hWaitHandle; + HANDLE hMraMrimProxyData; + +} MRA_FILES_QUEUE_ITEM; + + + +struct MRA_FILES_THREADPROC_PARAMS +{ + HANDLE hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; +}; + + + +//#define MEMALLOC(Size) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(Size+sizeof(SIZE_T))) +//#define MEMREALLOC(Mem,Size) HeapReAlloc(GetProcessHeap(),(HEAP_ZERO_MEMORY),(LPVOID)Mem,(Size+sizeof(SIZE_T))) +//#define MEMFREE(Mem) if (Mem) {HeapFree(GetProcessHeap(),0,(LPVOID)Mem);Mem=NULL;} + + +DWORD MraFilesQueueItemFindByID (HANDLE hFilesQueueHandle,DWORD dwIDRequest,MRA_FILES_QUEUE_ITEM **ppmrafqFilesQueueItem); +//DWORD MraFilesQueueItemFindByEMail (HANDLE hFilesQueueHandle,LPSTR lpszEMail,SIZE_T dwEMailSize,MRA_FILES_QUEUE_ITEM **ppmrafqFilesQueueItem); +void MraFilesQueueItemFree (MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem); +SIZE_T MraFilesQueueGetLocalAddressesList (LPSTR lpszBuff,SIZE_T dwBuffSize,DWORD dwPort); + +BOOL MraFilesQueueHandCheck (HANDLE hConnection,MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem); +void MraFilesQueueConnectionReceived (HANDLE hNewConnection,DWORD dwRemoteIP,void *pExtra); + +void MraFilesQueueRecvThreadProc (LPVOID lpParameter); +void MraFilesQueueSendThreadProc (LPVOID lpParameter); + + + +void MraFilesQueueDlgEnableDirectConsControls(HWND hWndDlg,BOOL bEnabled) +{ + 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 + }; + EnableControlsArray(hWndDlg,(WORD*)&wMraFilesControlsList,SIZEOF(wMraFilesControlsList),bEnabled); + EnableWindow(GetDlgItem(hWndDlg,IDC_FILE_SEND_EXTRA_ADDRESS),(bEnabled && IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_ADD_EXTRA_ADDRESS))); +} + +INT_PTR CALLBACK MraFilesQueueDlgProcOpts(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg){ + case WM_INITDIALOG: + { + WCHAR szBuff[MAX_PATH]; + + TranslateDialogDefault(hWndDlg); + + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_ENABLE_DIRECT_CONN,DB_Mra_GetByte(NULL,"FileSendEnableDirectConn",MRA_DEF_FS_ENABLE_DIRECT_CONN)); + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_NOOUTCONNECTIONONRECEIVE,DB_Mra_GetByte(NULL,"FileSendNoOutConnOnRcv",MRA_DEF_FS_NO_OUT_CONN_ON_RCV)); + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_NOOUTCONNECTIONONSEND,DB_Mra_GetByte(NULL,"FileSendNoOutConnOnSend",MRA_DEF_FS_NO_OUT_CONN_ON_SEND)); + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_IGNORYADDITIONALPORTS,DB_Mra_GetByte(NULL,"FileSendIgnoryAdditionalPorts",MRA_DEF_FS_IGNORY_ADDITIONAL_PORTS)); + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_HIDE_MY_ADDRESSES,DB_Mra_GetByte(NULL,"FileSendHideMyAddresses",MRA_DEF_FS_HIDE_MY_ADDRESSES)); + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_ADD_EXTRA_ADDRESS,DB_Mra_GetByte(NULL,"FileSendAddExtraAddresses",MRA_DEF_FS_ADD_EXTRA_ADDRESSES)); + if (DB_Mra_GetStaticStringW(NULL,"FileSendExtraAddresses",szBuff,SIZEOF(szBuff),NULL)) + { + SET_DLG_ITEM_TEXT(hWndDlg,IDC_FILE_SEND_EXTRA_ADDRESS,szBuff); + } + + CHECK_DLG_BUTTON(hWndDlg,IDC_FILE_SEND_ENABLE_MRIMPROXY_CONS,DB_Mra_GetByte(NULL,"FileSendEnableMRIMProxyCons",MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS)); + + SetDlgItemInt(hWndDlg,IDC_FILE_SEND_BLOCK_SIZE,DB_Mra_GetDword(NULL,"FileSendBlockSize",MRA_DEFAULT_FILE_SEND_BLOCK_SIZE),FALSE); + + MraFilesQueueDlgEnableDirectConsControls(hWndDlg,IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_ENABLE_DIRECT_CONN)); + } + return(TRUE); + case WM_COMMAND: + if (LOWORD(wParam)==IDC_FILE_SEND_ENABLE_DIRECT_CONN) + { + MraFilesQueueDlgEnableDirectConsControls(hWndDlg,IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_ENABLE_DIRECT_CONN)); + } + + if (LOWORD(wParam)==IDC_FILE_SEND_ADD_EXTRA_ADDRESS) + { + EnableWindow(GetDlgItem(hWndDlg,IDC_FILE_SEND_EXTRA_ADDRESS),IS_DLG_BUTTON_CHECKED(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: + { + WCHAR szBuff[MAX_PATH]; + + DB_Mra_SetByte(NULL,"FileSendEnableDirectConn",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_ENABLE_DIRECT_CONN)); + DB_Mra_SetByte(NULL,"FileSendNoOutConnOnRcv",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_NOOUTCONNECTIONONRECEIVE)); + DB_Mra_SetByte(NULL,"FileSendNoOutConnOnSend",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_NOOUTCONNECTIONONSEND)); + DB_Mra_SetByte(NULL,"FileSendIgnoryAdditionalPorts",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_IGNORYADDITIONALPORTS)); + DB_Mra_SetByte(NULL,"FileSendHideMyAddresses",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_HIDE_MY_ADDRESSES)); + DB_Mra_SetByte(NULL,"FileSendAddExtraAddresses",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_ADD_EXTRA_ADDRESS)); + GET_DLG_ITEM_TEXT(hWndDlg,IDC_FILE_SEND_EXTRA_ADDRESS,szBuff,SIZEOF(szBuff)); + DB_Mra_SetStringW(NULL,"FileSendExtraAddresses",szBuff); + DB_Mra_SetDword(NULL,"FileSendBlockSize",(DWORD)GetDlgItemInt(hWndDlg,IDC_FILE_SEND_BLOCK_SIZE,NULL,FALSE)); + DB_Mra_SetByte(NULL,"FileSendEnableMRIMProxyCons",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_FILE_SEND_ENABLE_MRIMPROXY_CONS)); + } + return(TRUE); + } + break; + } +return(FALSE); +} + + + +DWORD MraFilesQueueInitialize(DWORD dwSendTimeOutInterval,HANDLE *phFilesQueueHandle) +{ + DWORD dwRetErrorCode; + + if (phFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue; + + pmrafqFilesQueue=(MRA_FILES_QUEUE*)MEMALLOC(sizeof(MRA_FILES_QUEUE)); + if (pmrafqFilesQueue) + { + dwRetErrorCode=ListMTInitialize(&pmrafqFilesQueue->lmtListMT,0); + if (dwRetErrorCode==NO_ERROR) + { + pmrafqFilesQueue->dwSendTimeOutInterval=dwSendTimeOutInterval; + (*phFilesQueueHandle)=(HANDLE)pmrafqFilesQueue; + }else{ + MEMFREE(pmrafqFilesQueue); + } + }else{ + dwRetErrorCode=GetLastError(); + } + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +void MraFilesQueueDestroy(HANDLE hFilesQueueHandle) +{ + if (hFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + while(ListMTItemGetFirst(&pmrafqFilesQueue->lmtListMT,NULL,(LPVOID*)&pmrafqFilesQueueItem)==NO_ERROR) + { + MraFilesQueueItemFree(pmrafqFilesQueueItem); + } + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + + ListMTDestroy(&pmrafqFilesQueue->lmtListMT); + MEMFREE(pmrafqFilesQueue); + } +} + + +DWORD MraFilesQueueItemFindByID(HANDLE hFilesQueueHandle,DWORD dwIDRequest,MRA_FILES_QUEUE_ITEM **ppmrafqFilesQueueItem) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + LIST_MT_ITERATOR lmtiIterator; + + dwRetErrorCode=ERROR_NOT_FOUND; + ListMTLock(&pmrafqFilesQueue->lmtListMT); + ListMTIteratorMoveFirst(&pmrafqFilesQueue->lmtListMT,&lmtiIterator); + do + {// цикл + if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&pmrafqFilesQueueItem)==NO_ERROR) + if (pmrafqFilesQueueItem->dwIDRequest==dwIDRequest) + { + if (ppmrafqFilesQueueItem) (*ppmrafqFilesQueueItem)=pmrafqFilesQueueItem; + dwRetErrorCode=NO_ERROR; + break; + } + }while(ListMTIteratorMoveNext(&lmtiIterator)); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +HANDLE MraFilesQueueItemProxyByID(HANDLE hFilesQueueHandle,DWORD dwIDRequest) +{ + HANDLE hRet=NULL; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + if (MraFilesQueueItemFindByID(hFilesQueueHandle,dwIDRequest,&pmrafqFilesQueueItem)==NO_ERROR) + { + hRet=pmrafqFilesQueueItem->hMraMrimProxyData; + } +return(hRet); +} + + +/*DWORD MraFilesQueueItemFindByEMail(HANDLE hFilesQueueHandle,LPSTR lpszEMail,SIZE_T dwEMailSize,MRA_FILES_QUEUE_ITEM **ppmrafqFilesQueueItem) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle) + { + CHAR szEMailLocal[MAX_EMAIL_LEN]; + SIZE_T dwEMailLocalSize; + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + LIST_MT_ITERATOR lmtiIterator; + + dwRetErrorCode=ERROR_NOT_FOUND; + ListMTLock(&pmrafqFilesQueue->lmtListMT); + ListMTIteratorMoveFirst(&pmrafqFilesQueue->lmtListMT,&lmtiIterator); + do + {// цикл + if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&pmrafqFilesQueueItem)==NO_ERROR) + if (DB_Mra_GetStaticStringA(pmrafqFilesQueueItem->hContact,"e-mail",szEMailLocal,SIZEOF(szEMailLocal),&dwEMailLocalSize)) + if (dwEMailSize==dwEMailLocalSize) + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszEMail,dwEMailSize,szEMailLocal,dwEMailLocalSize)==CSTR_EQUAL) + { + if (ppmrafqFilesQueueItem) (*ppmrafqFilesQueueItem)=pmrafqFilesQueueItem; + dwRetErrorCode=NO_ERROR; + break; + } + }while(ListMTIteratorMoveNext(&lmtiIterator)); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +}*/ + + +void MraFilesQueueItemFree(MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem) +{ + LIST_MT *plmtListMT=(LIST_MT*)pmrafqFilesQueueItem->lmtListMTItem.lpListMT; + + for(SIZE_T i=0;idwFilesCount;i++) + { + MEMFREE(pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName); + } + MEMFREE(pmrafqFilesQueueItem->pmfqfFiles); + MEMFREE(pmrafqFilesQueueItem->pwszFilesList); + MEMFREE(pmrafqFilesQueueItem->pwszDescription); + MraAddrListFree(&pmrafqFilesQueueItem->malAddrList); + MraMrimProxyFree(pmrafqFilesQueueItem->hMraMrimProxyData); + MEMFREE(pmrafqFilesQueueItem->lpwszPath); + ListMTLock(plmtListMT); + ListMTItemDelete(plmtListMT,&pmrafqFilesQueueItem->lmtListMTItem); + ListMTUnLock(plmtListMT); + MEMFREE(pmrafqFilesQueueItem); +} + + + + + +SIZE_T MraFilesQueueGetLocalAddressesList(LPSTR lpszBuff,SIZE_T dwBuffSize,DWORD dwPort) +{ + CHAR szHostName[MAX_PATH]={0}; + LPSTR lpszCurPos=lpszBuff; + + if (DB_Mra_GetByte(NULL,"FileSendHideMyAddresses",MRA_DEF_FS_HIDE_MY_ADDRESSES)) + {// не выдаём врагу наш IP адрес!!! :) + if (DB_Mra_GetByte(NULL,"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(DB_Mra_GetDword(NULL,"IP",0)); + if (dwSelfExternalIP) + { + memmove(&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); + } + + if (gethostname(szHostName,SIZEOF(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++; + } + } + } + + if (DB_Mra_GetByte(NULL,"FileSendAddExtraAddresses",MRA_DEF_FS_ADD_EXTRA_ADDRESSES))// добавляем произвольный адрес + if (DB_Mra_GetStaticStringA(NULL,"FileSendExtraAddresses",szHostName,SIZEOF(szHostName),NULL)) + { + lpszCurPos+=mir_snprintf(lpszCurPos,(dwBuffSize-((SIZE_T)lpszCurPos-(SIZE_T)lpszBuff)),"%s:%lu;",szHostName,dwPort); + } +return((lpszCurPos-lpszBuff)); +} + + + + +DWORD MraFilesQueueAddReceive(HANDLE hFilesQueueHandle,DWORD dwFlags,HANDLE hContact,DWORD dwIDRequest,LPWSTR lpwszFiles,SIZE_T dwFilesSize,LPSTR lpszAddreses,SIZE_T dwAddresesSize) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle && dwIDRequest) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + pmrafqFilesQueueItem=(MRA_FILES_QUEUE_ITEM*)MEMALLOC(sizeof(MRA_FILES_QUEUE_ITEM)+sizeof(LPSTR)+64); + if (pmrafqFilesQueueItem) + { + WCHAR szBuff[MAX_PATH]; + LPWSTR lpwszCurrentItem,lpwszDelimiter,lpwszEndItem; + SIZE_T dwMemSize,dwAllocatedCount,dwFileNameTotalSize; + CCSDATA ccs; + PROTORECVFILET prf; + + //pmrafqFilesQueueItem->lmtListMTItem; + pmrafqFilesQueueItem->bIsWorking=TRUE; + pmrafqFilesQueueItem->dwSendTime=GetTickCount(); + pmrafqFilesQueueItem->dwIDRequest=dwIDRequest; + pmrafqFilesQueueItem->dwFlags=dwFlags; + pmrafqFilesQueueItem->hContact=hContact; + if (DB_Mra_GetByte(NULL,"FileSendEnableMRIMProxyCons",MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS)) pmrafqFilesQueueItem->hMraMrimProxyData=MraMrimProxyCreate(); + + + dwFileNameTotalSize=0; + dwAllocatedCount=ALLOCATED_COUNT; + pmrafqFilesQueueItem->dwFilesCount=0; + pmrafqFilesQueueItem->dwFilesTotalSize=0; + pmrafqFilesQueueItem->pmfqfFiles=(MRA_FILES_QUEUE_FILE*)MEMALLOC((sizeof(MRA_FILES_QUEUE_FILE)*dwAllocatedCount)); + lpwszCurrentItem=lpwszFiles; + while(TRUE) + { + lpwszDelimiter=(LPWSTR)MemoryFind(((SIZE_T)lpwszCurrentItem-(SIZE_T)lpwszFiles),lpwszFiles,(dwFilesSize*sizeof(WCHAR)),";",2); + if (lpwszDelimiter) + { + lpwszEndItem=(LPWSTR)MemoryFind((((SIZE_T)lpwszDelimiter+2)-(SIZE_T)lpwszFiles),lpwszFiles,(dwFilesSize*sizeof(WCHAR)),";",2); + if (lpwszEndItem) + { + if (pmrafqFilesQueueItem->dwFilesCount==dwAllocatedCount) + { + dwAllocatedCount*=2; + pmrafqFilesQueueItem->pmfqfFiles=(MRA_FILES_QUEUE_FILE*)MEMREALLOC(pmrafqFilesQueueItem->pmfqfFiles,(sizeof(MRA_FILES_QUEUE_FILE)*dwAllocatedCount)); + } + + dwMemSize=((SIZE_T)lpwszDelimiter-(SIZE_T)lpwszCurrentItem); + pmrafqFilesQueueItem->pmfqfFiles[pmrafqFilesQueueItem->dwFilesCount].lpwszName=(LPWSTR)MEMALLOC(dwMemSize); + memmove(pmrafqFilesQueueItem->pmfqfFiles[pmrafqFilesQueueItem->dwFilesCount].lpwszName,lpwszCurrentItem,dwMemSize); + pmrafqFilesQueueItem->pmfqfFiles[pmrafqFilesQueueItem->dwFilesCount].dwSize=StrToUNum64((LPSTR)((SIZE_T)lpwszDelimiter+1),((SIZE_T)lpwszEndItem-((SIZE_T)lpwszDelimiter+1))); + pmrafqFilesQueueItem->dwFilesTotalSize+=pmrafqFilesQueueItem->pmfqfFiles[pmrafqFilesQueueItem->dwFilesCount].dwSize; + pmrafqFilesQueueItem->pmfqfFiles[pmrafqFilesQueueItem->dwFilesCount].dwNameLen=(dwMemSize/sizeof(WCHAR)); + dwFileNameTotalSize+=dwMemSize; + + pmrafqFilesQueueItem->dwFilesCount++; + lpwszCurrentItem=(lpwszEndItem+1); + }else{ + break; + } + }else{ + break; + } + } + pmrafqFilesQueueItem->pmfqfFiles=(MRA_FILES_QUEUE_FILE*)MEMREALLOC(pmrafqFilesQueueItem->pmfqfFiles,(sizeof(MRA_FILES_QUEUE_FILE)*(pmrafqFilesQueueItem->dwFilesCount+4))); + + dwMemSize=(((pmrafqFilesQueueItem->dwFilesCount+4)*64)+(dwFileNameTotalSize*sizeof(WCHAR))+(dwAddresesSize*sizeof(WCHAR))+128); + pmrafqFilesQueueItem->pwszFilesList=(LPWSTR)MEMALLOC(dwMemSize); + pmrafqFilesQueueItem->pwszDescription=(LPWSTR)MEMALLOC(dwMemSize); + + + lpwszDelimiter=pmrafqFilesQueueItem->pwszFilesList; + lpwszCurrentItem=pmrafqFilesQueueItem->pwszDescription; + StrFormatByteSizeW(pmrafqFilesQueueItem->dwFilesTotalSize,szBuff,SIZEOF(szBuff)); + lpwszCurrentItem+=mir_sntprintf(lpwszCurrentItem,((dwMemSize-((SIZE_T)lpwszCurrentItem-(SIZE_T)pmrafqFilesQueueItem->pwszDescription))/sizeof(WCHAR)),L"%I64u Files (%s)\r\n",pmrafqFilesQueueItem->dwFilesCount,szBuff); + + // description + filesnames + for(SIZE_T i=0;idwFilesCount;i++) + { + lpwszDelimiter+=mir_sntprintf(lpwszDelimiter,((dwMemSize-((SIZE_T)lpwszDelimiter-(SIZE_T)pmrafqFilesQueueItem->pwszFilesList))/sizeof(WCHAR)),L"%s; ",pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName); + StrFormatByteSizeW(pmrafqFilesQueueItem->pmfqfFiles[i].dwSize,szBuff,SIZEOF(szBuff)); + lpwszCurrentItem+=mir_sntprintf(lpwszCurrentItem,((dwMemSize-((SIZE_T)lpwszCurrentItem-(SIZE_T)pmrafqFilesQueueItem->pwszDescription))/sizeof(WCHAR)),L"%s - %s\r\n",pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName,szBuff); + } + + lpwszCurrentItem+=MultiByteToWideChar(MRA_CODE_PAGE,0,lpszAddreses,dwAddresesSize,lpwszCurrentItem,((dwMemSize-((SIZE_T)lpwszCurrentItem-(SIZE_T)pmrafqFilesQueueItem->pwszDescription))/sizeof(WCHAR))); + (*lpwszCurrentItem)=0; + //lpwszCurrentItem++; + + + MraAddrListGetFromBuff(lpszAddreses,dwAddresesSize,&pmrafqFilesQueueItem->malAddrList); + MraAddrListStoreToContact(pmrafqFilesQueueItem->hContact,&pmrafqFilesQueueItem->malAddrList); + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + ListMTItemAdd(&pmrafqFilesQueue->lmtListMT,&pmrafqFilesQueueItem->lmtListMTItem,pmrafqFilesQueueItem); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + + + // Send chain event + + ccs.szProtoService=PSR_FILE; + ccs.hContact=hContact; + ccs.wParam=0; + ccs.lParam=(LPARAM)&prf; + prf.flags=PREF_UNICODE; + prf.timestamp=_time32(NULL); + prf.tszDescription=pmrafqFilesQueueItem->pwszDescription; + prf.fileCount=1;//pmrafqFilesQueueItem->dwFilesCount; + prf.ptszFiles=&pmrafqFilesQueueItem->pwszFilesList; + prf.lParam=dwIDRequest; + + CallService(MS_PROTO_CHAINRECV,0,(LPARAM)&ccs); + + dwRetErrorCode=NO_ERROR; + }else{ + dwRetErrorCode=GetLastError(); + } + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + + +DWORD MraFilesQueueAddSend(HANDLE hFilesQueueHandle,DWORD dwFlags,HANDLE hContact,LPWSTR *plpwszFiles,SIZE_T dwFilesCount,DWORD *pdwIDRequest) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + + pmrafqFilesQueueItem=(MRA_FILES_QUEUE_ITEM*)MEMALLOC(sizeof(MRA_FILES_QUEUE_ITEM)+sizeof(LPSTR)+64); + if (pmrafqFilesQueueItem) + { + SIZE_T i; + ULARGE_INTEGER uliFileSize; + WIN32_FILE_ATTRIBUTE_DATA wfad; + + //pmrafqFilesQueueItem->lmtListMTItem; + pmrafqFilesQueueItem->bIsWorking=TRUE; + pmrafqFilesQueueItem->dwSendTime=GetTickCount(); + pmrafqFilesQueueItem->dwIDRequest=InterlockedIncrement((LONG volatile*)&masMraSettings.dwCMDNum);// уникальный, рандомный идентификатор + pmrafqFilesQueueItem->dwFlags=dwFlags; + pmrafqFilesQueueItem->hContact=hContact; + if (DB_Mra_GetByte(NULL,"FileSendEnableMRIMProxyCons",MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS)) pmrafqFilesQueueItem->hMraMrimProxyData=MraMrimProxyCreate(); + pmrafqFilesQueueItem->dwFilesCount=dwFilesCount; + pmrafqFilesQueueItem->pmfqfFiles=(MRA_FILES_QUEUE_FILE*)MEMALLOC((sizeof(MRA_FILES_QUEUE_FILE)*(pmrafqFilesQueueItem->dwFilesCount+1))); + pmrafqFilesQueueItem->dwFilesTotalSize=0; + + for(i=0;idwFilesCount;i++) + { + if (GetFileAttributesExW(plpwszFiles[i],GetFileExInfoStandard,&wfad)) + { + uliFileSize.LowPart=wfad.nFileSizeLow; + uliFileSize.HighPart=wfad.nFileSizeHigh; + pmrafqFilesQueueItem->pmfqfFiles[i].dwSize=uliFileSize.QuadPart; + pmrafqFilesQueueItem->dwFilesTotalSize+=uliFileSize.QuadPart; + }else{ + pmrafqFilesQueueItem->pmfqfFiles[i].dwSize=0; + } + pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen=lstrlenW(plpwszFiles[i]); + pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName=(LPWSTR)MEMALLOC((pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen*sizeof(WCHAR))); + if (pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName) + { + memmove(pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName,plpwszFiles[i],(pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen*sizeof(WCHAR))); + } + } + //pmrafqFilesQueueItem->malAddrList.dwAddrCount=0; + //pmrafqFilesQueueItem->pmfqaAddreses=NULL; + pmrafqFilesQueueItem->bSending=TRUE; + if (pdwIDRequest) (*pdwIDRequest)=pmrafqFilesQueueItem->dwIDRequest; + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + ListMTItemAdd(&pmrafqFilesQueue->lmtListMT,&pmrafqFilesQueueItem->lmtListMTItem,pmrafqFilesQueueItem); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + + { + MRA_FILES_THREADPROC_PARAMS *pmftpp=(MRA_FILES_THREADPROC_PARAMS*)MEMALLOC(sizeof(MRA_FILES_THREADPROC_PARAMS)); + pmftpp->hFilesQueueHandle=hFilesQueueHandle; + pmftpp->pmrafqFilesQueueItem=pmrafqFilesQueueItem; + + pmrafqFilesQueueItem->hThread=(HANDLE)mir_forkthread((pThreadFunc)MraFilesQueueSendThreadProc,pmftpp); + } + + dwRetErrorCode=NO_ERROR; + }else{ + dwRetErrorCode=GetLastError(); + } + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + + +DWORD MraFilesQueueAccept(HANDLE hFilesQueueHandle,DWORD dwIDRequest,LPWSTR lpwszPath,SIZE_T dwPathSize) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle && lpwszPath && dwPathSize) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + if ((dwRetErrorCode=MraFilesQueueItemFindByID(hFilesQueueHandle,dwIDRequest,&pmrafqFilesQueueItem))==NO_ERROR) + { + MRA_FILES_THREADPROC_PARAMS *pmftpp=(MRA_FILES_THREADPROC_PARAMS*)MEMALLOC(sizeof(MRA_FILES_THREADPROC_PARAMS)); + pmrafqFilesQueueItem->lpwszPath=(LPWSTR)MEMALLOC((dwPathSize*sizeof(WCHAR))); + pmrafqFilesQueueItem->dwPathSize=dwPathSize; + memmove(pmrafqFilesQueueItem->lpwszPath,lpwszPath,(dwPathSize*sizeof(WCHAR))); + + if ( (*(WCHAR*)(pmrafqFilesQueueItem->lpwszPath+(pmrafqFilesQueueItem->dwPathSize-1)))!='\\') + {// add slash at the end if needed + (*(WCHAR*)(pmrafqFilesQueueItem->lpwszPath+pmrafqFilesQueueItem->dwPathSize))='\\'; + pmrafqFilesQueueItem->dwPathSize++; + (*(WCHAR*)(pmrafqFilesQueueItem->lpwszPath+pmrafqFilesQueueItem->dwPathSize))=0; + } + + pmftpp->hFilesQueueHandle=hFilesQueueHandle; + pmftpp->pmrafqFilesQueueItem=pmrafqFilesQueueItem; + + pmrafqFilesQueueItem->hThread=(HANDLE)mir_forkthread((pThreadFunc)MraFilesQueueRecvThreadProc,pmftpp); + } + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +DWORD MraFilesQueueCancel(HANDLE hFilesQueueHandle,DWORD dwIDRequest,BOOL bSendDecline) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + if ((dwRetErrorCode=MraFilesQueueItemFindByID(hFilesQueueHandle,dwIDRequest,&pmrafqFilesQueueItem))==NO_ERROR) + {//***deb closesocket, send message to thread + InterlockedExchange((volatile LONG*)&pmrafqFilesQueueItem->bIsWorking,FALSE); + + if (bSendDecline) + { + CHAR szEMail[MAX_EMAIL_LEN]; + SIZE_T dwEMailSize; + + if (DB_Mra_GetStaticStringA(pmrafqFilesQueueItem->hContact,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize)) + { + MraSendCommand_FileTransferAck(FILE_TRANSFER_STATUS_DECLINE,szEMail,dwEMailSize,dwIDRequest,NULL,0); + } + } + + MraMrimProxyCloseConnection(pmrafqFilesQueueItem->hMraMrimProxyData); + + Netlib_CloseHandle(pmrafqFilesQueueItem->hListen); + pmrafqFilesQueueItem->hListen=NULL; + + Netlib_CloseHandle(pmrafqFilesQueueItem->hConnection); + pmrafqFilesQueueItem->hConnection=NULL; + + SetEvent(pmrafqFilesQueueItem->hWaitHandle); + + if (pmrafqFilesQueueItem->hThread==NULL) + { + MraFilesQueueItemFree(pmrafqFilesQueueItem); + } + } + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +DWORD MraFilesQueueStartMrimProxy(HANDLE hFilesQueueHandle,DWORD dwIDRequest) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle && DB_Mra_GetByte(NULL,"FileSendEnableMRIMProxyCons",MRA_DEF_FS_ENABLE_MRIM_PROXY_CONS)) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + if ((dwRetErrorCode=MraFilesQueueItemFindByID(hFilesQueueHandle,dwIDRequest,&pmrafqFilesQueueItem))==NO_ERROR) + {//***deb + if (pmrafqFilesQueueItem->bSending==FALSE) + {// receiving + SetEvent(pmrafqFilesQueueItem->hWaitHandle);// cancel wait incomming connection + }else{// sending + + } + } + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +DWORD MraFilesQueueFree(HANDLE hFilesQueueHandle,DWORD dwIDRequest) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + LIST_MT_ITERATOR lmtiIterator; + + dwRetErrorCode=ERROR_NOT_FOUND; + ListMTLock(&pmrafqFilesQueue->lmtListMT); + ListMTIteratorMoveFirst(&pmrafqFilesQueue->lmtListMT,&lmtiIterator); + do + {// цикл + if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&pmrafqFilesQueueItem)==NO_ERROR) + if (pmrafqFilesQueueItem->dwIDRequest==dwIDRequest) + { + MraFilesQueueItemFree(pmrafqFilesQueueItem); + dwRetErrorCode=NO_ERROR; + break; + } + }while(ListMTIteratorMoveNext(&lmtiIterator)); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +DWORD MraFilesQueueSendMirror(HANDLE hFilesQueueHandle,DWORD dwIDRequest,LPSTR lpszAddreses,SIZE_T dwAddresesSize) +{ + DWORD dwRetErrorCode; + + if (hFilesQueueHandle) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem; + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + if ((dwRetErrorCode=MraFilesQueueItemFindByID(hFilesQueueHandle,dwIDRequest,&pmrafqFilesQueueItem))==NO_ERROR) + {// + MraAddrListGetFromBuff(lpszAddreses,dwAddresesSize,&pmrafqFilesQueueItem->malAddrList); + MraAddrListStoreToContact(pmrafqFilesQueueItem->hContact,&pmrafqFilesQueueItem->malAddrList); + + pmrafqFilesQueueItem->hConnection=NULL; + SetEvent(pmrafqFilesQueueItem->hWaitHandle); + } + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + }else{ + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + + +BOOL MraFilesQueueHandCheck(HANDLE hConnection,MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem) +{ + BOOL bRet=FALSE; + + if (hConnection && pmrafqFilesQueueItem) + { + CHAR szEMail[MAX_EMAIL_LEN]={0},szEMailMy[MAX_EMAIL_LEN]={0}; + BYTE btBuff[((MAX_EMAIL_LEN*2)+(sizeof(MRA_FT_HELLO)*2)+8)]={0}; + SIZE_T dwEMailSize,dwEMailMySize,dwBuffSize; + + DB_Mra_GetStaticStringA(NULL,"e-mail",szEMailMy,SIZEOF(szEMailMy),&dwEMailMySize);BuffToLowerCase(szEMailMy,szEMailMy,dwEMailMySize); + DB_Mra_GetStaticStringA(pmrafqFilesQueueItem->hContact,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize);BuffToLowerCase(szEMail,szEMail,dwEMailSize); + + if (pmrafqFilesQueueItem->bSending==FALSE) + {// receiving + dwBuffSize=(mir_snprintf((LPSTR)btBuff,SIZEOF(btBuff),"%s %s",MRA_FT_HELLO,szEMailMy)+1); + if (dwBuffSize==Netlib_Send(hConnection,(LPSTR)btBuff,dwBuffSize,0)) + {// my email sended + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_INITIALISING,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + dwBuffSize=Netlib_Recv(hConnection,(LPSTR)btBuff,sizeof(btBuff),0); + if ((dwEMailSize+sizeof(MRA_FT_HELLO)+1)==dwBuffSize) + {// email received + mir_snprintf(((LPSTR)btBuff+dwBuffSize),(SIZEOF(btBuff)-dwBuffSize),"%s %s",MRA_FT_HELLO,szEMail); + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,(LPSTR)btBuff,dwBuffSize,((LPSTR)btBuff+dwBuffSize),dwBuffSize)==CSTR_EQUAL) + {// email verifyed + bRet=TRUE; + } + } + } + }else{// sending + dwBuffSize=Netlib_Recv(hConnection,(LPSTR)btBuff,sizeof(btBuff),0); + if ((dwEMailSize+sizeof(MRA_FT_HELLO)+1)==dwBuffSize) + {// email received + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_INITIALISING,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + mir_snprintf(((LPSTR)btBuff+dwBuffSize),(SIZEOF(btBuff)-dwBuffSize),"%s %s",MRA_FT_HELLO,szEMail); + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,(LPSTR)btBuff,dwBuffSize,((LPSTR)btBuff+dwBuffSize),dwBuffSize)==CSTR_EQUAL) + {// email verifyed + dwBuffSize=(mir_snprintf((LPSTR)btBuff,SIZEOF(btBuff),"%s %s",MRA_FT_HELLO,szEMailMy)+1); + if (dwBuffSize==Netlib_Send(hConnection,(LPSTR)btBuff,dwBuffSize,0)) + {// my email sended + bRet=TRUE; + } + } + } + } + } +return(bRet); +} + + +HANDLE MraFilesQueueConnectOut(MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem) +{ + HANDLE hRet; + + if (pmrafqFilesQueueItem) + { + if (DB_Mra_GetByte(NULL,"FileSendEnableDirectConn",MRA_DEF_FS_ENABLE_DIRECT_CONN) && InterlockedExchangeAdd((volatile LONG*)&pmrafqFilesQueueItem->bIsWorking,0) && ((pmrafqFilesQueueItem->bSending==FALSE && DB_Mra_GetByte(NULL,"FileSendNoOutConnOnRcv",MRA_DEF_FS_NO_OUT_CONN_ON_RCV)==FALSE) || (pmrafqFilesQueueItem->bSending==TRUE && DB_Mra_GetByte(NULL,"FileSendNoOutConnOnSend",MRA_DEF_FS_NO_OUT_CONN_ON_SEND)==FALSE))) + { + BOOL bFiltering=FALSE,bIsHTTPSProxyUsed=IsHTTPSProxyUsed(masMraSettings.hNetlibUser); + DWORD dwLocalPort,dwConnectReTryCount,dwCurConnectReTryCount; + SIZE_T i,dwAddrCount; + NETLIBOPENCONNECTION nloc={0}; + + dwLocalPort=0; + + if (DB_Mra_GetByte(NULL,"FileSendIgnoryAdditionalPorts",MRA_DEF_FS_IGNORY_ADDITIONAL_PORTS) || bIsHTTPSProxyUsed) + {// фильтруем порты для одного IP, вместо 3 будем коннектится только к одному + if (bIsHTTPSProxyUsed) + {// через https прокси только 443 порт + dwLocalPort=MRA_SERVER_PORT_HTTPS; + }else{ + if ((dwLocalPort=DB_Mra_GetWord(NULL,"ServerPort",MRA_DEFAULT_SERVER_PORT))==MRA_SERVER_PORT_STANDART_NLB) dwLocalPort=MRA_SERVER_PORT_STANDART; + } + + dwAddrCount=0; + for(i=0;imalAddrList.dwAddrCount;i++) + { + if (dwLocalPort==pmrafqFilesQueueItem->malAddrList.pmaliAddress[i].dwPort) + { + bFiltering=TRUE; + dwAddrCount++; + } + } + } + if (bFiltering==FALSE) dwAddrCount=pmrafqFilesQueueItem->malAddrList.dwAddrCount; + + if (dwAddrCount) + { + pmrafqFilesQueueItem->hConnection=NULL; + dwConnectReTryCount=DB_Mra_GetDword(NULL,"ConnectReTryCountFileSend",MRA_DEFAULT_CONN_RETRY_COUNT_FILES); + nloc.cbSize=sizeof(nloc); + nloc.flags=NLOCF_V2; + nloc.timeout=DB_Mra_GetDword(NULL,"TimeOutConnectFileSend",((MRA_TIMEOUT_DIRECT_CONN-1)/(dwAddrCount*dwConnectReTryCount)));// -1 сек чтобы был запас + if (nloc.timeoutMRA_TIMEOUT_CONN_МАХ) nloc.timeout=MRA_TIMEOUT_CONN_МАХ; + + for(i=0;imalAddrList.dwAddrCount;i++) + {// Set up the sockaddr structure + if (dwLocalPort==pmrafqFilesQueueItem->malAddrList.pmaliAddress[i].dwPort || bFiltering==FALSE) + { + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_CONNECTING,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + + nloc.szHost=inet_ntoa((*((in_addr*)&pmrafqFilesQueueItem->malAddrList.pmaliAddress[i].dwAddr))); + nloc.wPort=(WORD)pmrafqFilesQueueItem->malAddrList.pmaliAddress[i].dwPort; + + dwCurConnectReTryCount=dwConnectReTryCount; + do{ + pmrafqFilesQueueItem->hConnection=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)masMraSettings.hNetlibUser,(LPARAM)&nloc); + }while(--dwCurConnectReTryCount && pmrafqFilesQueueItem->hConnection==NULL); + + if (pmrafqFilesQueueItem->hConnection) + { + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + if (MraFilesQueueHandCheck(pmrafqFilesQueueItem->hConnection,pmrafqFilesQueueItem)) + {// связь установленная с тем кем нужно + DB_Mra_SetDword(pmrafqFilesQueueItem->hContact,"OldIP",DB_Mra_GetDword(pmrafqFilesQueueItem->hContact,"IP",0)); + DB_Mra_SetDword(pmrafqFilesQueueItem->hContact,"IP",HTONL(pmrafqFilesQueueItem->malAddrList.pmaliAddress[i].dwAddr)); + break; + }else{// кажется не туда подключились :) + Netlib_CloseHandle(pmrafqFilesQueueItem->hConnection); + pmrafqFilesQueueItem->hConnection=NULL; + } + } + } + } + } + } + hRet=pmrafqFilesQueueItem->hConnection; + }else{ + hRet=NULL; + } +return(hRet); +} + + +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 MraFilesQueueConnectIn(MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem) +{ + HANDLE hRet=NULL; + + if (pmrafqFilesQueueItem) + if (InterlockedExchangeAdd((volatile LONG*)&pmrafqFilesQueueItem->bIsWorking,0)) + { + CHAR szEMail[MAX_EMAIL_LEN]; + SIZE_T dwEMailSize; + + if (DB_Mra_GetStaticStringA(pmrafqFilesQueueItem->hContact,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize)) + { + CHAR szAddrList[2048]={0}; + SIZE_T dwAddrListSize; + + if (DB_Mra_GetByte(NULL,"FileSendEnableDirectConn",MRA_DEF_FS_ENABLE_DIRECT_CONN)) + {// копируем адреса в соответствии с правилами и начинаем слушать порт + NETLIBBIND nlbBind={0}; + + nlbBind.cbSize=sizeof(nlbBind); + nlbBind.pfnNewConnectionV2=MraFilesQueueConnectionReceived; + nlbBind.wPort=0; + nlbBind.pExtra=(LPVOID)pmrafqFilesQueueItem; + + pmrafqFilesQueueItem->hListen=(HANDLE)CallService(MS_NETLIB_BINDPORT,(WPARAM)masMraSettings.hNetlibUser,(LPARAM)&nlbBind); + if (pmrafqFilesQueueItem->hListen) + { + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_LISTENING,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + dwAddrListSize=MraFilesQueueGetLocalAddressesList(szAddrList,sizeof(szAddrList),nlbBind.wPort); + }else{// не смогли слушать порт, хз почему. + ShowFormatedErrorMessage(L"Files exchange: cant create listen soscket, will try connect to remonte host. Error",GetLastError()); + + //dwAddrListSize=0; + memmove(szAddrList,MRA_FILES_NULL_ADDRR,sizeof(MRA_FILES_NULL_ADDRR)); + dwAddrListSize=(sizeof(MRA_FILES_NULL_ADDRR)-1); + } + }else{// подставляем ложный адрес, чтобы точно не подключились и не слушаем порт + memmove(szAddrList,MRA_FILES_NULL_ADDRR,sizeof(MRA_FILES_NULL_ADDRR)); + dwAddrListSize=(sizeof(MRA_FILES_NULL_ADDRR)-1); + } + + if (dwAddrListSize) + { + pmrafqFilesQueueItem->hWaitHandle=CreateEvent(NULL,TRUE,FALSE,NULL); + if (pmrafqFilesQueueItem->bSending==FALSE) + {// запрашиваем зеркальное соединение, тк сами подключится не смогли + MraSendCommand_FileTransferAck(FILE_TRANSFER_MIRROR,szEMail,dwEMailSize,pmrafqFilesQueueItem->dwIDRequest,(LPBYTE)szAddrList,dwAddrListSize); + }else{// здесь отправляем запрос на передачу(установление соединения) + // создаём текстовый список файлов для отправки другой стороне + LPWSTR lpwszFiles,lpwszCurPos; + SIZE_T dwFilesSize; + + dwFilesSize=((MAX_PATH*2)*pmrafqFilesQueueItem->dwFilesCount); + lpwszFiles=(LPWSTR)MEMALLOC((dwFilesSize*sizeof(WCHAR))); + if (lpwszFiles) + { + lpwszCurPos=lpwszFiles; + for(SIZE_T i=0;idwFilesCount;i++) + { + lpwszCurPos+=mir_sntprintf(lpwszCurPos,(dwFilesSize-((SIZE_T)lpwszCurPos-(SIZE_T)lpwszFiles)),L"%s;%I64u;",GetFileNameFromFullPathW(pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName,pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen),pmrafqFilesQueueItem->pmfqfFiles[i].dwSize); + } + dwFilesSize=(lpwszCurPos-lpwszFiles);// size in WCHARs + + if (pmrafqFilesQueueItem->hMraMrimProxyData) + {// устанавливаем данные для майловской прокси, если она разрешена + LPSTR lpszFiles; + SIZE_T dwFilesSizeA; + + dwFilesSizeA=WideCharToMultiByte(MRA_CODE_PAGE,0,lpwszFiles,dwFilesSize,NULL,0,NULL,NULL); + lpszFiles=(LPSTR)MEMALLOC((dwFilesSizeA+MAX_PATH)); + if (lpszFiles) + { + dwFilesSizeA=WideCharToMultiByte(MRA_CODE_PAGE,0,lpwszFiles,dwFilesSize,lpszFiles,(dwFilesSizeA+MAX_PATH),NULL,NULL); + MraMrimProxySetData(pmrafqFilesQueueItem->hMraMrimProxyData,szEMail,dwEMailSize,pmrafqFilesQueueItem->dwIDRequest,MRIM_PROXY_TYPE_FILES,lpszFiles,dwFilesSizeA,NULL,0,NULL); + MEMFREE(lpszFiles); + } + //MraMrimProxySetData(pmrafqFilesQueueItem->hMraMrimProxyData,szEMail,dwEMailSize,pmrafqFilesQueueItem->dwIDRequest,MRIM_PROXY_TYPE_FILES,(LPSTR)lpwszFiles,dwFilesSize,NULL,0,NULL); + } + MraSendCommand_FileTransfer(szEMail,dwEMailSize,pmrafqFilesQueueItem->dwIDRequest,pmrafqFilesQueueItem->dwFilesTotalSize,lpwszFiles,dwFilesSize,szAddrList,dwAddrListSize); + + MEMFREE(lpwszFiles); + } + } + WaitForSingleObjectEx(pmrafqFilesQueueItem->hWaitHandle,INFINITE,FALSE); + CloseHandle(pmrafqFilesQueueItem->hWaitHandle); + pmrafqFilesQueueItem->hWaitHandle=NULL; + } + } + hRet=pmrafqFilesQueueItem->hConnection; + } +return(hRet); +} + +// This function is called from the Netlib when someone is connecting to +// one of our incomming DC ports +void MraFilesQueueConnectionReceived(HANDLE hNewConnection,DWORD dwRemoteIP,void *pExtra) +{ + if (pExtra) + { + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem=(MRA_FILES_QUEUE_ITEM*)pExtra; + + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + if (MraFilesQueueHandCheck(hNewConnection,pmrafqFilesQueueItem)) + {// связь установленная с тем кем нужно + pmrafqFilesQueueItem->hConnection=hNewConnection; + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + DB_Mra_SetDword(pmrafqFilesQueueItem->hContact,"OldIP",DB_Mra_GetDword(pmrafqFilesQueueItem->hContact,"IP",0)); + DB_Mra_SetDword(pmrafqFilesQueueItem->hContact,"IP",dwRemoteIP); + SetEvent(pmrafqFilesQueueItem->hWaitHandle); + }else{// кажется кто то не туда подключилися :) + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_LISTENING,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + Netlib_CloseHandle(hNewConnection); + } + }else{ + Netlib_CloseHandle(hNewConnection); + MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,TranslateW(L"MraFilesQueueConnectionReceived: connection accepted, but pExtra=NULL, this is miranda bug.")); + DebugBreak(); + } +} + + + +void MraFilesQueueRecvThreadProc(LPVOID lpParameter) +{ + DWORD dwRetErrorCode=NO_ERROR; + + if (lpParameter) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem=((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->pmrafqFilesQueueItem; + + 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={0}; + + MEMFREE(lpParameter); + + bFailed=TRUE; + bConnected=FALSE; + nls.cbSize=sizeof(nls); + pfts.cbSize=sizeof(pfts); + pfts.hContact=pmrafqFilesQueueItem->hContact; + pfts.flags=(PFTS_RECEIVING|PFTS_UNICODE);// pfts.sending=pmrafqFilesQueueItem->bSending; //true if sending, false if receiving + //pfts.files; + pfts.totalFiles=pmrafqFilesQueueItem->dwFilesCount; + //pfts.currentFileNumber=0; + pfts.totalBytes=pmrafqFilesQueueItem->dwFilesTotalSize; + //pfts.totalProgress=0; + pfts.wszWorkingDir=pmrafqFilesQueueItem->lpwszPath; + //pfts.currentFile; + //pfts.currentFileSize; + //pfts.currentFileProgress; + //pfts.currentFileTime; //as seconds since 1970 + + if (MraFilesQueueConnectOut(pmrafqFilesQueueItem)) + { + bConnected=TRUE; + }else{ + if (MraFilesQueueConnectIn(pmrafqFilesQueueItem)) + { + bConnected=TRUE; + }else{ + if (InterlockedExchangeAdd((volatile LONG*)&pmrafqFilesQueueItem->bIsWorking,0)) + { + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKRESULT_CONNECTPROXY,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + if (MraMrimProxyConnect(pmrafqFilesQueueItem->hMraMrimProxyData,&pmrafqFilesQueueItem->hConnection)==NO_ERROR) + {// подключились к прокси, проверяем та ли сессия (ещё раз, на этот раз сами) + if (MraFilesQueueHandCheck(pmrafqFilesQueueItem->hConnection,pmrafqFilesQueueItem)) + {// связь установленная с тем кем нужно// pmrafqFilesQueueItem->bSending + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + bConnected=TRUE; + } + } + } + } + } + + if (bConnected) + {// email verifyed + bFailed=FALSE; + for(i=0;idwFilesCount;i++) + {// receiving files + pfts.currentFileNumber=i; + pfts.wszCurrentFile=wszFileName; + pfts.currentFileSize=pmrafqFilesQueueItem->pmfqfFiles[i].dwSize; + pfts.currentFileProgress=0; + //pfts.currentFileTime; //as seconds since 1970 + + if ((pmrafqFilesQueueItem->dwPathSize+pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen)lpwszPath,(pmrafqFilesQueueItem->dwPathSize*sizeof(WCHAR))); + memmove((wszFileName+pmrafqFilesQueueItem->dwPathSize),pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName,((pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen+1)*sizeof(WCHAR))); + wszFileName[pmrafqFilesQueueItem->dwPathSize+pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen]=0; + }else{ + dwRetErrorCode=ERROR_BAD_PATHNAME; + ShowFormatedErrorMessage(L"Receive files: error",dwRetErrorCode); + bFailed=TRUE; + break; + } + + //***deb add + //dwBuffSizeUsed=ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_FILERESUME,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,(LPARAM)&pfts); + + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_NEXTFILE,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + + //dwBuffSizeUsed=(mir_snprintf((LPSTR)btBuff,SIZEOF(btBuff),"%s %S",MRA_FT_GET_FILE,pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName)+1); + memmove(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,pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName,pmrafqFilesQueueItem->pmfqfFiles[i].dwNameLen,(LPSTR)(btBuff+sizeof(MRA_FT_GET_FILE)),(SIZEOF(btBuff)-sizeof(MRA_FT_GET_FILE)),NULL,NULL); + btBuff[dwBuffSizeUsed]=0; + dwBuffSizeUsed++; + + if (dwBuffSizeUsed==Netlib_Send(pmrafqFilesQueueItem->hConnection,(LPSTR)btBuff,dwBuffSizeUsed,0)) + {// file request sended + hFile=CreateFileW(wszFileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + if (hFile!=INVALID_HANDLE_VALUE) + {// file opened/created, pre allocating disk space, for best perfomance + bOK=FALSE; + + liFileSize.QuadPart=(LONGLONG)pmrafqFilesQueueItem->pmfqfFiles[i].dwSize; + if (SetFilePointerEx(hFile,liFileSize,NULL,FILE_BEGIN)) + if (SetEndOfFile(hFile)) + { + liFileSize.QuadPart=0; + bOK=SetFilePointerEx(hFile,liFileSize,NULL,FILE_BEGIN); + } + + if (bOK) + {// disk space pre allocated + bOK=FALSE; + bContinue=TRUE; + dwUpdateTimeNext=GetTickCount(); + nls.dwTimeout=(1000*DB_Mra_GetDword(NULL,"TimeOutReceiveFileData",MRA_DEF_FS_TIMEOUT_RECV)); + nls.hReadConns[0]=pmrafqFilesQueueItem->hConnection; + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_DATA,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,(LPARAM)&pfts); + + while(bContinue) + { + switch(CallService(MS_NETLIB_SELECT,0,(LPARAM)&nls)){ + case SOCKET_ERROR: + case 0:// Time out + dwRetErrorCode=GetLastError(); + ShowFormatedErrorMessage(L"Receive files: error on receive file data",dwRetErrorCode); + bContinue=FALSE; + break; + case 1: + dwReceived=Netlib_Recv(pmrafqFilesQueueItem->hConnection,(LPSTR)&btBuff,SIZEOF(btBuff),0); + if (dwReceived==0 || dwReceived==SOCKET_ERROR) + { + dwRetErrorCode=GetLastError(); + ShowFormatedErrorMessage(L"Receive files: error on receive file data",dwRetErrorCode); + bContinue=FALSE; + }else{ + if (WriteFile(hFile,(LPVOID)&btBuff,dwReceived,&dwReceived,NULL)) + { + pfts.currentFileProgress+=dwReceived; + pfts.totalProgress+=dwReceived; + + // progress updates + dwUpdateTimeCur=GetTickCount(); + if (dwUpdateTimeNext<=dwUpdateTimeCur || pfts.currentFileProgress>=pmrafqFilesQueueItem->pmfqfFiles[i].dwSize) + {// we update it + dwUpdateTimeNext=dwUpdateTimeCur+MRA_FILES_QUEUE_PROGRESS_INTERVAL; + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_DATA,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,(LPARAM)&pfts); + + if (pfts.currentFileProgress>=pmrafqFilesQueueItem->pmfqfFiles[i].dwSize) + {// file received + bOK=TRUE; + bContinue=FALSE; + } + } + }else{// err on write file + dwRetErrorCode=GetLastError(); + ShowFormatedErrorMessage(L"Receive files: cant write file data, error",dwRetErrorCode); + bContinue=FALSE; + } + } + break; + } + }// end while + }else{// err allocating file disk space + dwRetErrorCode=GetLastError(); + mir_sntprintf(szErrorText,SIZEOF(szErrorText),TranslateW(L"Receive files: cant allocate disk space for file, size %lu bytes, error"),pmrafqFilesQueueItem->pmfqfFiles[i].dwSize); + ShowFormatedErrorMessage(szErrorText,dwRetErrorCode); + } + CloseHandle(hFile); + + if (bOK==FALSE) + {// file recv failed + DeleteFileW(wszFileName); + bFailed=TRUE; + break; + } + }else{// err on open file + dwRetErrorCode=GetLastError(); + mir_sntprintf(szErrorText,SIZEOF(szErrorText),TranslateW(L"Receive files: cant open file %s, error"),wszFileName); + ShowFormatedErrorMessage(szErrorText,dwRetErrorCode); + bFailed=TRUE; + break; + } + }else{// err on send request for file + dwRetErrorCode=GetLastError(); + mir_sntprintf(szErrorText,SIZEOF(szErrorText),TranslateW(L"Receive files: request for file %s not sended, error"),pmrafqFilesQueueItem->pmfqfFiles[i].lpwszName); + ShowFormatedErrorMessage(szErrorText,NO_ERROR); + bFailed=TRUE; + break; + } + }// end for + + Netlib_CloseHandle(pmrafqFilesQueueItem->hConnection); + pmrafqFilesQueueItem->hConnection=NULL; + } + + if (bFailed) + { + CHAR szEMail[MAX_EMAIL_LEN]; + SIZE_T dwEMailSize; + + if (DB_Mra_GetStaticStringA(pmrafqFilesQueueItem->hContact,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize)) + { + MraSendCommand_FileTransferAck(FILE_TRANSFER_STATUS_ERROR,szEMail,dwEMailSize,pmrafqFilesQueueItem->dwIDRequest,NULL,0); + } + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_FAILED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + }else{ + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_SUCCESS,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + } + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + MraFilesQueueItemFree(pmrafqFilesQueueItem); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + } +} + + + +void MraFilesQueueSendThreadProc(LPVOID lpParameter) +{ + DWORD dwRetErrorCode=NO_ERROR; + + if (lpParameter) + { + MRA_FILES_QUEUE *pmrafqFilesQueue=(MRA_FILES_QUEUE*)((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->hFilesQueueHandle; + MRA_FILES_QUEUE_ITEM *pmrafqFilesQueueItem=((MRA_FILES_THREADPROC_PARAMS*)lpParameter)->pmrafqFilesQueueItem; + + CHAR szFileName[MAX_FILEPATH]={0}; + WCHAR szErrorText[2048]; + BYTE btBuff[BUFF_SIZE_RCV]; + BOOL bFailed=TRUE,bOK,bConnected=FALSE; + DWORD dwReceived,dwSendBlockSize,dwUpdateTimeNext,dwUpdateTimeCur; + HANDLE hFile; + SIZE_T i,j,dwBuffSizeUsed=0; + LPWSTR lpwszFileName; + PROTOFILETRANSFERSTATUS pfts={0}; + + MEMFREE(lpParameter); + + pfts.cbSize=sizeof(pfts); + pfts.hContact=pmrafqFilesQueueItem->hContact; + pfts.flags=(PFTS_SENDING|PFTS_UNICODE);// pfts.sending=pmrafqFilesQueueItem->bSending; //true if sending, false if receiving + //pfts.files; + pfts.totalFiles=pmrafqFilesQueueItem->dwFilesCount; + //pfts.currentFileNumber=0; + pfts.totalBytes=pmrafqFilesQueueItem->dwFilesTotalSize; + //pfts.totalProgress=0; + pfts.wszWorkingDir=pmrafqFilesQueueItem->lpwszPath; + //pfts.currentFile; + //pfts.currentFileSize; + //pfts.currentFileProgress; + //pfts.currentFileTime; //as seconds since 1970 + + dwSendBlockSize=DB_Mra_GetDword(NULL,"FileSendBlockSize",MRA_DEFAULT_FILE_SEND_BLOCK_SIZE); + if (dwSendBlockSize>SIZEOF(btBuff)) dwSendBlockSize=SIZEOF(btBuff); + if (dwSendBlockSize<512) dwSendBlockSize=MRA_DEFAULT_FILE_SEND_BLOCK_SIZE; + + if (MraFilesQueueConnectIn(pmrafqFilesQueueItem)) + { + bConnected=TRUE; + }else{ + if (MraFilesQueueConnectOut(pmrafqFilesQueueItem)) + { + bConnected=TRUE; + }else{ + if (InterlockedExchangeAdd((volatile LONG*)&pmrafqFilesQueueItem->bIsWorking,0)) + { + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKRESULT_CONNECTPROXY,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + if (MraMrimProxyConnect(pmrafqFilesQueueItem->hMraMrimProxyData,&pmrafqFilesQueueItem->hConnection)==NO_ERROR) + {// подключились к прокси, проверяем та ли сессия (ещё раз, на этот раз сами) + if (MraFilesQueueHandCheck(pmrafqFilesQueueItem->hConnection,pmrafqFilesQueueItem)) + {// связь установленная с тем кем нужно// pmrafqFilesQueueItem->bSending + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_CONNECTED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + bConnected=TRUE; + } + } + } + } + } + + if (bConnected) + {// email verifyed + bFailed=FALSE; + for(i=0;idwFilesCount;i++) + {// sending files + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_NEXTFILE,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + + dwBuffSizeUsed=0; + while(TRUE) + { + dwReceived=Netlib_Recv(pmrafqFilesQueueItem->hConnection,((LPSTR)btBuff+dwBuffSizeUsed),(SIZEOF(btBuff)-dwBuffSizeUsed),0); + if (dwReceived==0 || dwReceived==SOCKET_ERROR) + {// err on receive file name to send + dwRetErrorCode=GetLastError(); + ShowFormatedErrorMessage(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==FALSE) + {// ...received + if (dwBuffSizeUsed>(sizeof(MRA_FT_GET_FILE)+1)) + {// file name received + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,(LPSTR)btBuff,(sizeof(MRA_FT_GET_FILE)-1),MRA_FT_GET_FILE,(sizeof(MRA_FT_GET_FILE)-1))==CSTR_EQUAL) + {// MRA_FT_GET_FILE verifyed + bFailed=TRUE; + for(j=0;jdwFilesCount;j++) + { + lpwszFileName=GetFileNameFromFullPathW(pmrafqFilesQueueItem->pmfqfFiles[j].lpwszName,pmrafqFilesQueueItem->pmfqfFiles[j].dwNameLen); + szFileName[WideCharToMultiByte(MRA_CODE_PAGE,0,lpwszFileName,(pmrafqFilesQueueItem->pmfqfFiles[j].dwNameLen-(lpwszFileName-pmrafqFilesQueueItem->pmfqfFiles[j].lpwszName)),szFileName,SIZEOF(szFileName),NULL,NULL)]=0; + + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,(((LPSTR)btBuff)+sizeof(MRA_FT_GET_FILE)),(dwBuffSizeUsed-(sizeof(MRA_FT_GET_FILE)+1)),szFileName,-1)==CSTR_EQUAL) + { + bFailed=FALSE; + break; + } + } + + if (bFailed==FALSE) + { + hFile=CreateFileW(pmrafqFilesQueueItem->pmfqfFiles[j].lpwszName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,(FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN),NULL); + if (hFile!=INVALID_HANDLE_VALUE) + { + bOK=FALSE; + dwUpdateTimeNext=GetTickCount(); + pfts.currentFileNumber=i; + pfts.wszCurrentFile=pmrafqFilesQueueItem->pmfqfFiles[j].lpwszName; + pfts.currentFileSize=pmrafqFilesQueueItem->pmfqfFiles[j].dwSize; + pfts.currentFileProgress=0; + //pfts.currentFileTime; //as seconds since 1970 + + WideCharToMultiByte(MRA_CODE_PAGE,0,pmrafqFilesQueueItem->pmfqfFiles[j].lpwszName,pmrafqFilesQueueItem->pmfqfFiles[j].dwNameLen,szFileName,SIZEOF(szFileName),NULL,NULL); + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_DATA,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,(LPARAM)&pfts); + + while(TRUE) + {// read and sending + if (ReadFile(hFile,btBuff,dwSendBlockSize,(DWORD*)&dwBuffSizeUsed,NULL)) + { + dwReceived=Netlib_Send(pmrafqFilesQueueItem->hConnection,(LPSTR)btBuff,dwBuffSizeUsed,0); + if (dwBuffSizeUsed==dwReceived) + { + pfts.currentFileProgress+=dwBuffSizeUsed; + pfts.totalProgress+=dwBuffSizeUsed; + + // progress updates + dwUpdateTimeCur=GetTickCount(); + if (dwUpdateTimeNext<=dwUpdateTimeCur || pfts.currentFileProgress>=pmrafqFilesQueueItem->pmfqfFiles[j].dwSize) + {// we update it + dwUpdateTimeNext=dwUpdateTimeCur+MRA_FILES_QUEUE_PROGRESS_INTERVAL; + + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_DATA,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,(LPARAM)&pfts); + + if (pfts.currentFileProgress>=pmrafqFilesQueueItem->pmfqfFiles[j].dwSize) + {// file received + bOK=TRUE; + break; + } + } + }else{// err on send file data + dwRetErrorCode=GetLastError(); + ShowFormatedErrorMessage(L"Send files: error on send file data",dwRetErrorCode); + break; + } + }else{// read failure + dwRetErrorCode=GetLastError(); + ShowFormatedErrorMessage(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_sntprintf(szErrorText,SIZEOF(szErrorText),TranslateW(L"Send files: cant open file %s, error"),pmrafqFilesQueueItem->pmfqfFiles[j].lpwszName); + ShowFormatedErrorMessage(szErrorText,dwRetErrorCode); + bFailed=TRUE; + break; + } + }else{ + mir_sntprintf(szErrorText,SIZEOF(szErrorText),TranslateW(L"Send files: requested file: %S - not found in send files list."),(((LPSTR)btBuff)+sizeof(MRA_FT_GET_FILE))); + ShowFormatedErrorMessage(szErrorText,NO_ERROR); + bFailed=TRUE; + break; + } + }else{// err on receive, trash + ShowFormatedErrorMessage(L"Send files: bad file send request - invalid header",NO_ERROR); + bFailed=TRUE; + break; + } + }else{// bad file name or trash + ShowFormatedErrorMessage(L"Send files: bad file send request - to small packet",NO_ERROR); + bFailed=TRUE; + break; + } + }else{ + break; + } + }// end for + + Netlib_CloseHandle(pmrafqFilesQueueItem->hConnection); + pmrafqFilesQueueItem->hConnection=NULL; + } + + if (bFailed) + { + CHAR szEMail[MAX_EMAIL_LEN]; + SIZE_T dwEMailSize; + + if (DB_Mra_GetStaticStringA(pmrafqFilesQueueItem->hContact,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize)) + { + MraSendCommand_FileTransferAck(FILE_TRANSFER_STATUS_ERROR,szEMail,dwEMailSize,pmrafqFilesQueueItem->dwIDRequest,NULL,0); + } + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_FAILED,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + }else{ + ProtoBroadcastAck(PROTOCOL_NAMEA,pmrafqFilesQueueItem->hContact,ACKTYPE_FILE,ACKRESULT_SUCCESS,(HANDLE)pmrafqFilesQueueItem->dwIDRequest,0); + } + + ListMTLock(&pmrafqFilesQueue->lmtListMT); + MraFilesQueueItemFree(pmrafqFilesQueueItem); + ListMTUnLock(&pmrafqFilesQueue->lmtListMT); + } +} -- cgit v1.2.3