Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1720 lines
55 KiB

  1. /* file: mbftsend.cpp */
  2. #include "mbftpch.h"
  3. #include "mbftsend.hpp"
  4. #include "fileio.hpp"
  5. #include "messages.hpp"
  6. #include "mbftapi.hpp"
  7. #define _MAX_SEND_PACKETS 1
  8. ULONG g_nSendDisbandDelay = 5000; // Previous: Twenty seconds!
  9. ULONG g_nChannelResponseDelay = 60000;
  10. MBFTPrivateSend::MBFTPrivateSend
  11. (
  12. LPMBFTENGINE lpParentEngine,
  13. MBFTEVENTHANDLE EventHandle,
  14. T120ChannelID wMBFTUserID,
  15. ULONG MaxDataLength
  16. )
  17. :
  18. MBFTSession(lpParentEngine, EventHandle, MBFT_PRIVATE_SEND_TYPE),
  19. m_PrivateMBFTControlChannel(0),
  20. m_PrivateMBFTDataChannel(0),
  21. m_lpUserArray(NULL),
  22. m_lpAcceptedUsersArray(NULL),
  23. m_iUserCount(0),
  24. m_MBFTChannelID(wMBFTUserID),
  25. m_MaxDataLength(MaxDataLength),
  26. m_LastUserCount(0),
  27. m_ResponseCount(0),
  28. m_AcceptCount(0),
  29. m_RejectCount(0),
  30. m_AbortedCount(0),
  31. m_AcknowledgeCount(0),
  32. m_CurrentFileSize(0),
  33. m_lTotalBytesRead(0),
  34. m_lpDataBuffer(NULL),
  35. m_bProshareTransfer(FALSE),
  36. m_bEOFAcknowledge(FALSE),
  37. m_lpFile(NULL),
  38. m_pszCurrentFilePath(NULL),
  39. m_CurrentFileHandle(0),
  40. m_AcceptedIndex(0),
  41. m_bSentFileOfferPDU(FALSE),
  42. m_bUnInitializing(FALSE),
  43. m_bAbortAllFiles(FALSE),
  44. m_bSendingFile(FALSE),
  45. m_bAbortFileSend(FALSE),
  46. m_SentFileStartPDU(FALSE),
  47. m_TimeOutValue(0),
  48. m_bCompressFiles(FALSE),
  49. m_bOKToDisbandChannel(TRUE),
  50. m_lpV42bisPointer(NULL),
  51. m_bFlushv42Compression(FALSE),
  52. m_bEventEndPosted(FALSE),
  53. m_State(EnumIdleNotInitialized)
  54. {
  55. }
  56. MBFTPrivateSend::~MBFTPrivateSend(void)
  57. {
  58. delete m_pszCurrentFilePath;
  59. delete m_lpUserArray;
  60. delete m_lpAcceptedUsersArray;
  61. delete m_lpDataBuffer;
  62. delete m_lpFile;
  63. }
  64. void MBFTPrivateSend::ConveneControlChannel(void)
  65. {
  66. if(m_lpParentEngine->MCSChannelConveneRequest())
  67. {
  68. m_State = EnumWaitConveneControlChannel;
  69. }
  70. else
  71. {
  72. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  73. UnInitialize();
  74. }
  75. }
  76. void MBFTPrivateSend::ConveneDataChannel(void)
  77. {
  78. if(m_lpParentEngine->MCSChannelConveneRequest())
  79. {
  80. m_State = EnumWaitConveneDataChannel;
  81. }
  82. else
  83. {
  84. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  85. UnInitialize();
  86. }
  87. }
  88. void MBFTPrivateSend::JoinControlChannel(void)
  89. {
  90. if(m_lpParentEngine->MCSChannelJoinRequest(m_PrivateMBFTControlChannel))
  91. {
  92. m_State = EnumWaitJoinControlChannel;
  93. }
  94. else
  95. {
  96. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  97. UnInitialize();
  98. }
  99. }
  100. BOOL MBFTPrivateSend::OnMCSChannelJoinConfirm
  101. (
  102. T120ChannelID wChannelId,
  103. BOOL bSuccess
  104. )
  105. {
  106. BOOL bReturn = FALSE;
  107. if(wChannelId == m_PrivateMBFTControlChannel)
  108. {
  109. if(m_State == EnumWaitJoinControlChannel)
  110. {
  111. if(bSuccess)
  112. {
  113. TRACESEND(" Control channel joined [%u]\n",wChannelId);
  114. ConveneDataChannel();
  115. }
  116. else
  117. {
  118. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  119. UnInitialize();
  120. }
  121. bReturn = TRUE;
  122. }
  123. }
  124. return(bReturn);
  125. }
  126. void MBFTPrivateSend::AdmitControlChannel(void)
  127. {
  128. if(m_lpParentEngine->MCSChannelAdmitRequest(m_PrivateMBFTControlChannel,
  129. m_lpUserArray,
  130. m_iUserCount))
  131. {
  132. TRACESEND(" Admit Control Channel Successful [%u]\n",m_PrivateMBFTControlChannel);
  133. }
  134. else
  135. {
  136. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  137. UnInitialize();
  138. }
  139. if(m_lpParentEngine->MCSChannelAdmitRequest(m_PrivateMBFTDataChannel,
  140. m_lpUserArray,
  141. m_iUserCount))
  142. {
  143. TRACESEND(" Admit Data Channel Successful [%u]\n",m_PrivateMBFTDataChannel);
  144. m_State = EnumWaitChannelResponsePDU;
  145. m_TimeOutValue = GetTickCount() + g_nChannelResponseDelay;
  146. }
  147. else
  148. {
  149. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  150. UnInitialize();
  151. }
  152. }
  153. BOOL MBFTPrivateSend::OnMCSChannelConveneConfirm
  154. (
  155. T120ChannelID wChannelId,
  156. BOOL bSuccess
  157. )
  158. {
  159. BOOL bReturn = FALSE;
  160. if(m_State == EnumWaitConveneControlChannel)
  161. {
  162. if(bSuccess)
  163. {
  164. TRACESEND(" Control channel convened [%u]\n",wChannelId);
  165. m_PrivateMBFTControlChannel = wChannelId;
  166. JoinControlChannel();
  167. }
  168. else
  169. {
  170. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  171. UnInitialize();
  172. }
  173. bReturn = TRUE;
  174. }
  175. else if(m_State == EnumWaitConveneDataChannel)
  176. {
  177. if(bSuccess)
  178. {
  179. TRACESEND(" Data channel convened [%u]\n",wChannelId);
  180. m_PrivateMBFTDataChannel = wChannelId;
  181. m_State = EnumWaitSendChannelInvitePDU;
  182. }
  183. else
  184. {
  185. ReportError(MBFT_PERMANENT_ERROR,iMBFT_UNKNOWN_ERROR,TRUE);
  186. UnInitialize();
  187. }
  188. bReturn = TRUE;
  189. }
  190. return(bReturn);
  191. }
  192. BOOL MBFTPrivateSend::SubmitFileSendRequest
  193. (
  194. SubmitFileSendMsg *pMsg
  195. )
  196. {
  197. BOOL bCompressFiles = pMsg->m_bCompressFiles;
  198. delete m_pszCurrentFilePath; // clean up any possible left over
  199. m_pszCurrentFilePath = pMsg->m_pszFilePath;
  200. m_CurrentFileHandle = pMsg->m_nFileHandle;
  201. pMsg->m_pszFilePath = NULL; // keep this pointer for furure use
  202. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  203. MBFT_ERROR_TYPES iErrorType = MBFT_PERMANENT_ERROR;
  204. //NOTE: Merely turning this flag to TRUE will NOT
  205. //enable compression. I have set it to FALSE here
  206. //so that certain stubbed routines will not be
  207. //entered. If you turn this flag to TRUE....
  208. //then...have your finger ready on the reset button!!
  209. //If you want to turn compression on, Then you have
  210. //to include a bunch of v42.bis compression files etc.
  211. bCompressFiles = FALSE;
  212. // get the peer list
  213. CPeerList *pPeerList = m_lpParentEngine->GetPeerList();
  214. ASSERT(! (pMsg->m_nUserID && pMsg->m_nNodeID));
  215. BOOL fBroadcast = (0 == pMsg->m_nUserID && 0 == pMsg->m_nNodeID);
  216. ULONG iNumNodes = 1;
  217. if (fBroadcast)
  218. {
  219. iNumNodes = pPeerList->GetCount();
  220. ASSERT(iNumNodes);
  221. }
  222. DBG_SAVE_FILE_LINE
  223. m_lpDataBuffer = new char[m_MaxDataLength + MAX_PATH + _iMBFT_FILEDATA_PDU_SUBTRACT]; // enough space for the largest PDU
  224. DBG_SAVE_FILE_LINE
  225. m_lpUserArray = new UserID[iNumNodes];
  226. DBG_SAVE_FILE_LINE
  227. m_lpAcceptedUsersArray = new UserID[iNumNodes];
  228. if (NULL == m_lpDataBuffer || NULL == m_lpUserArray || NULL == m_lpAcceptedUsersArray)
  229. {
  230. ERROR_OUT(("MBFTPrivateSend::SubmitFileSendRequest: allocation failure"));
  231. delete m_lpDataBuffer; m_lpDataBuffer = NULL;
  232. delete m_lpUserArray; m_lpUserArray = NULL;
  233. delete m_lpAcceptedUsersArray; m_lpAcceptedUsersArray = NULL;
  234. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  235. }
  236. if(iErrorCode == iMBFT_OK)
  237. {
  238. m_iUserCount = 0;
  239. ZeroMemory(m_lpUserArray, sizeof(UserID) * iNumNodes);
  240. ZeroMemory(m_lpAcceptedUsersArray, sizeof(UserID) * iNumNodes);
  241. m_bProshareTransfer = TRUE;
  242. m_bEOFAcknowledge = TRUE;
  243. if (fBroadcast)
  244. {
  245. CPeerData *lpPeer;
  246. pPeerList->Reset();
  247. while (NULL != (lpPeer = pPeerList->Iterate()))
  248. {
  249. if (lpPeer->GetUserID() != m_lpParentEngine->GetUserID())
  250. {
  251. m_lpUserArray[m_iUserCount++] = lpPeer->GetUserID();
  252. if(m_bProshareTransfer)
  253. {
  254. m_bProshareTransfer = lpPeer->GetIsProshareNode();
  255. }
  256. if(m_bEOFAcknowledge)
  257. {
  258. m_bEOFAcknowledge = lpPeer->GetEOFAcknowledge();
  259. }
  260. }
  261. } // while
  262. }
  263. else
  264. {
  265. CPeerData *lpPeer;
  266. pPeerList->Reset();
  267. while (NULL != (lpPeer = pPeerList->Iterate()))
  268. {
  269. if ((pMsg->m_nUserID && pMsg->m_nUserID == lpPeer->GetUserID())
  270. ||
  271. (pMsg->m_nNodeID && pMsg->m_nNodeID == lpPeer->GetNodeID()))
  272. {
  273. m_lpUserArray[m_iUserCount++] = lpPeer->GetUserID();
  274. if(m_bProshareTransfer)
  275. {
  276. m_bProshareTransfer = lpPeer->GetIsProshareNode();
  277. }
  278. if(m_bEOFAcknowledge)
  279. {
  280. m_bEOFAcknowledge = lpPeer->GetEOFAcknowledge();
  281. }
  282. break;
  283. }
  284. } // while
  285. if (NULL == lpPeer)
  286. {
  287. iErrorCode = iMBFT_RECIPIENT_NOT_FOUND;
  288. }
  289. }
  290. if(m_bCompressFiles)
  291. {
  292. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  293. }
  294. else
  295. {
  296. DBG_SAVE_FILE_LINE
  297. m_lpFile = new CMBFTFile;
  298. }
  299. if(!m_lpFile)
  300. {
  301. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  302. }
  303. if(iErrorCode == iMBFT_OK)
  304. {
  305. m_State = EnumFileSendPending;
  306. }
  307. }
  308. if(iErrorCode != iMBFT_OK)
  309. {
  310. // LOGERROR(iErrorCode,0,0);
  311. ReportError(iErrorType,iErrorCode,TRUE);
  312. TerminateSendSession();
  313. }
  314. return(iErrorCode == iMBFT_OK);
  315. }
  316. void MBFTPrivateSend::ReportSenderError
  317. (
  318. int iErrorType,
  319. int iErrorCode,
  320. MBFTFILEHANDLE hFile
  321. )
  322. {
  323. DBG_SAVE_FILE_LINE
  324. FileErrorPDU * lpNewPDU = new FileErrorPDU((hFile) ?
  325. LOWORD(hFile) :
  326. LOWORD(m_CurrentFileHandle),
  327. iErrorType,iErrorCode);
  328. if(lpNewPDU)
  329. {
  330. if(lpNewPDU->Encode())
  331. {
  332. for (ULONG Index = 0; Index < m_iUserCount; Index++)
  333. {
  334. m_lpParentEngine->SendDataRequest(m_lpUserArray[Index],
  335. APPLET_HIGH_PRIORITY,
  336. (LPBYTE)lpNewPDU->GetBuffer(),
  337. lpNewPDU->GetBufferLength());
  338. }
  339. }
  340. delete lpNewPDU;
  341. }
  342. }
  343. void MBFTPrivateSend::ReportError
  344. (
  345. int iErrorType,
  346. int iErrorCode,
  347. BOOL bIsLocalError,
  348. T120UserID SenderID,
  349. MBFTFILEHANDLE FileHandle)
  350. {
  351. T120UserID id = SenderID ? SenderID : m_MBFTChannelID;
  352. DBG_SAVE_FILE_LINE
  353. m_lpParentEngine->SafePostNotifyMessage(
  354. new FileErrorMsg(
  355. m_EventHandle,
  356. FileHandle ? FileHandle : m_CurrentFileHandle,
  357. iErrorType,
  358. iErrorCode,
  359. bIsLocalError,
  360. id));
  361. }
  362. void MBFTPrivateSend::TerminateSendSession(void)
  363. {
  364. UnInitialize();
  365. }
  366. void MBFTPrivateSend::UnInitialize
  367. (
  368. BOOL bShutDown
  369. )
  370. {
  371. BOOL bDataChannelDisbanded = FALSE;
  372. BOOL bControlChannelDisbanded = FALSE;
  373. if(m_State != EnumWaitForTermination)
  374. {
  375. m_State = EnumWaitForTermination;
  376. TRACESEND(" Uninit begin\n");
  377. if (m_bEOFAcknowledge)
  378. {
  379. m_TimeOutValue = 0;
  380. }
  381. else
  382. {
  383. m_TimeOutValue = GetTickCount() + g_nSendDisbandDelay;
  384. }
  385. TRACESEND(" Using TimeOutValue of %d\n", m_TimeOutValue);
  386. }
  387. m_bUnInitializing = TRUE;
  388. if(GetTickCount() >= m_TimeOutValue)
  389. {
  390. if(m_PrivateMBFTDataChannel)
  391. {
  392. if(m_lpParentEngine->MCSChannelDisbandRequest(m_PrivateMBFTDataChannel))
  393. {
  394. TRACESEND(" Uninit: Data Channel disbanded [%u]\n",m_PrivateMBFTDataChannel);
  395. bDataChannelDisbanded = TRUE;
  396. m_PrivateMBFTDataChannel = 0;
  397. }
  398. else if(m_lpParentEngine->GetLastSendDataError() == MCS_TRANSMIT_BUFFER_FULL)
  399. {
  400. TRACESEND("Transmit buffer for [%u] full, data channel disband failed\n",m_PrivateMBFTDataChannel);
  401. }
  402. else
  403. {
  404. TRACESEND("Unexpected error [%u] while disbanding data channel [%u]\n",
  405. m_lpParentEngine->GetLastSendDataError(),m_PrivateMBFTDataChannel);
  406. }
  407. }
  408. else
  409. {
  410. bDataChannelDisbanded = TRUE;
  411. }
  412. if(bDataChannelDisbanded)
  413. {
  414. if(m_PrivateMBFTControlChannel)
  415. {
  416. if(m_lpParentEngine->MCSChannelDisbandRequest(m_PrivateMBFTControlChannel))
  417. {
  418. TRACESEND(" Uninit: Control Channel disbanded [%u]\n",m_PrivateMBFTControlChannel);
  419. bControlChannelDisbanded = TRUE;
  420. m_PrivateMBFTControlChannel = 0;
  421. }
  422. else if(m_lpParentEngine->GetLastSendDataError() == MCS_TRANSMIT_BUFFER_FULL)
  423. {
  424. TRACESEND("Transmit buffer for [%u] full, control channel disband failed\n",m_PrivateMBFTDataChannel);
  425. }
  426. else
  427. {
  428. TRACESEND("Unexpected error [%u] while disbanding control channel [%u]\n",
  429. m_lpParentEngine->GetLastSendDataError(),m_PrivateMBFTDataChannel);
  430. }
  431. }
  432. else
  433. {
  434. bControlChannelDisbanded = TRUE;
  435. }
  436. }
  437. if(!bShutDown)
  438. {
  439. if(bDataChannelDisbanded && bControlChannelDisbanded)
  440. {
  441. DBG_SAVE_FILE_LINE
  442. m_lpParentEngine->SafePostMessage(new DeleteSessionMsg(this));
  443. if(!m_bEventEndPosted)
  444. {
  445. DBG_SAVE_FILE_LINE
  446. m_lpParentEngine->SafePostNotifyMessage(new FileEventEndNotifyMsg(m_EventHandle));
  447. m_bEventEndPosted = TRUE;
  448. }
  449. TRACESEND(" Uninit complete\n");
  450. }
  451. }
  452. else
  453. {
  454. TRACESEND(" Uninit complete\n");
  455. }
  456. }
  457. }
  458. void MBFTPrivateSend::SendChannelInvitePDU(void)
  459. {
  460. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  461. MBFT_ERROR_TYPES iErrorType = MBFT_PERMANENT_ERROR;
  462. DBG_SAVE_FILE_LINE
  463. LPPRIVATECHANNELINVITEPDU lpNewPDU = new PrivateChannelInvitePDU(m_PrivateMBFTControlChannel,
  464. m_PrivateMBFTDataChannel,
  465. FALSE);
  466. if(lpNewPDU)
  467. {
  468. if(lpNewPDU->Encode())
  469. {
  470. for (ULONG Index = m_LastUserCount;Index < m_iUserCount;Index++)
  471. {
  472. if(m_lpParentEngine->SendDataRequest(m_lpUserArray[Index],
  473. APPLET_HIGH_PRIORITY,
  474. (LPBYTE)lpNewPDU->GetBuffer(),
  475. lpNewPDU->GetBufferLength()))
  476. {
  477. TRACESEND(" Sent Channel invite PDU, Control Channel [%u], Data Channel [%u] to [%u]\n",m_PrivateMBFTControlChannel,m_PrivateMBFTDataChannel,m_lpUserArray[Index]);
  478. m_LastUserCount++;
  479. }
  480. else
  481. {
  482. m_State = EnumWaitSendChannelInvitePDU;
  483. break;
  484. }
  485. }
  486. if(Index >= m_iUserCount)
  487. {
  488. AdmitControlChannel();
  489. }
  490. }
  491. else
  492. {
  493. iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
  494. }
  495. delete lpNewPDU;
  496. }
  497. else
  498. {
  499. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  500. }
  501. if(iErrorCode != iMBFT_OK)
  502. {
  503. ReportError(iErrorType,iErrorCode,TRUE);
  504. UnInitialize();
  505. }
  506. }
  507. BOOL MBFTPrivateSend::OnReceivedFileAbortPDU
  508. (
  509. T120ChannelID wChannelId,
  510. T120Priority iPriority,
  511. T120UserID SenderID,
  512. LPFILEABORTPDU lpFileAbortPDU,
  513. BOOL IsUniformSendData
  514. )
  515. {
  516. MBFTFILEHANDLE hFile = lpFileAbortPDU->GetFileHandle();
  517. if (hFile && hFile == m_CurrentFileHandle)
  518. {
  519. if (m_bUnInitializing)
  520. {
  521. OnControlNotification(hFile,
  522. FileTransferControlMsg::EnumConductorAbortFile,
  523. NULL,
  524. NULL);
  525. }
  526. return TRUE; // handled
  527. }
  528. return FALSE; // not handled
  529. }
  530. void MBFTPrivateSend::DoStateMachine(void)
  531. {
  532. if(m_State == EnumFileSendPending)
  533. {
  534. ConveneControlChannel();
  535. }
  536. else if(m_State == EnumWaitRequestControlConvene)
  537. {
  538. ConveneControlChannel();
  539. }
  540. else if(m_State == EnumWaitRequestJoinControl)
  541. {
  542. JoinControlChannel();
  543. }
  544. else if(m_State == EnumWaitRequestDataConvene)
  545. {
  546. ConveneDataChannel();
  547. }
  548. else if(m_State == EnumWaitSendChannelInvitePDU)
  549. {
  550. SendChannelInvitePDU();
  551. }
  552. else if(m_State == EnumSendNonStandardPDU)
  553. {
  554. TRACESEND(" Not Sending a NonStandardPDU");
  555. m_State = EnumSendFileOfferPDU;
  556. SendFileOfferPDU();
  557. }
  558. else if(m_State == EnumSendFileOfferPDU)
  559. {
  560. SendFileOfferPDU();
  561. }
  562. else if(m_State == EnumSendFileStartPDU)
  563. {
  564. SendFileStartPDU();
  565. }
  566. else if(m_State == EnumSendFileDataPDU)
  567. {
  568. SendFileDataPDU();
  569. }
  570. else if(m_State == EnumTerminateCurrentSend)
  571. {
  572. TerminateCurrentSend();
  573. }
  574. else if(m_State == EnumWaitForTermination)
  575. {
  576. UnInitialize();
  577. }
  578. else if(m_State == EnumWaitChannelResponsePDU)
  579. {
  580. if(GetTickCount() >= m_TimeOutValue)
  581. {
  582. // LOGERROR(iMBFT_TIMEOUT_ERROR,0,0);
  583. ReportError(MBFT_PERMANENT_ERROR,iMBFT_TIMEOUT_ERROR,TRUE);
  584. UnInitialize();
  585. }
  586. }
  587. return;
  588. }
  589. BOOL MBFTPrivateSend::OnReceivedPrivateChannelResponsePDU
  590. (
  591. T120ChannelID wChannelId,
  592. T120Priority iPriority,
  593. T120UserID SenderID,
  594. LPPRIVATECHANNELRESPONSEPDU lpNewPDU,
  595. BOOL IsUniformSendData
  596. )
  597. {
  598. BOOL bReturn = FALSE;
  599. if(m_State == EnumWaitChannelResponsePDU)
  600. {
  601. if(wChannelId == m_MBFTChannelID &&
  602. lpNewPDU->GetControlChannel() == m_PrivateMBFTControlChannel)
  603. {
  604. bReturn = TRUE;
  605. TRACESEND(" Received Channel response PDU from [%u]\n",SenderID);
  606. for (ULONG Index = 0; Index < m_iUserCount; Index++)
  607. {
  608. if(m_lpUserArray[Index] == SenderID)
  609. {
  610. m_ResponseCount++;
  611. }
  612. }
  613. if(!lpNewPDU->GetWasChannelJoined())
  614. {
  615. ReportError(MBFT_INFORMATIVE_ERROR,
  616. iMBFT_RECEIVER_ABORTED,
  617. FALSE,
  618. SenderID,
  619. _iMBFT_PROSHARE_ALL_FILES);
  620. RemoveUserFromList(SenderID);
  621. }
  622. if(m_iUserCount)
  623. {
  624. if(m_ResponseCount >= m_iUserCount)
  625. {
  626. m_State = (! m_bProshareTransfer) ? EnumSendFileOfferPDU :
  627. EnumSendNonStandardPDU;
  628. }
  629. }
  630. }
  631. }
  632. return(bReturn);
  633. }
  634. void MBFTPrivateSend::SendFileOfferPDU(void)
  635. {
  636. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  637. MBFT_ERROR_TYPES iErrorType = MBFT_TRANSIENT_ERROR;
  638. m_AcceptCount = 0;
  639. m_RejectCount = 0;
  640. m_ResponseCount = 0;
  641. m_AcknowledgeCount = 0;
  642. m_lTotalBytesRead = 0;
  643. m_SentFileStartPDU = FALSE;
  644. m_AbortedCount = 0;
  645. m_bSentFileOfferPDU = FALSE;
  646. m_AcceptedIndex = 0;
  647. ::ZeroMemory(m_lpAcceptedUsersArray, sizeof(UserID) * m_iUserCount);
  648. if (m_lpFile->Open(m_pszCurrentFilePath, CMBFTFile::OpenReadOnly | CMBFTFile::OpenBinary))
  649. {
  650. m_CurrentFileSize = m_lpFile->GetFileSize();
  651. m_CurrentDateTime = m_lpFile->GetFileDateTime();
  652. DBG_SAVE_FILE_LINE
  653. LPFILEOFFERPDU lpNewPDU = new FileOfferPDU(GetFileNameFromPath(m_pszCurrentFilePath),
  654. LOWORD(m_CurrentFileHandle),
  655. m_CurrentFileSize,
  656. m_CurrentDateTime,
  657. m_PrivateMBFTDataChannel,TRUE,
  658. m_lpParentEngine->GetRosterInstance(),
  659. 0, NULL, 0, 0);
  660. if(lpNewPDU)
  661. {
  662. if(lpNewPDU->Encode())
  663. {
  664. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTControlChannel,
  665. APPLET_HIGH_PRIORITY,
  666. (LPBYTE)lpNewPDU->GetBuffer(),
  667. lpNewPDU->GetBufferLength()))
  668. {
  669. TRACESEND(" Transmitted File Offer PDU for [%u] on [%u]\n",LOWORD(m_CurrentFileHandle),m_PrivateMBFTControlChannel);
  670. //Now that we have sent a FileOfferPDU, we can't disband the channel
  671. //without notice....
  672. m_bOKToDisbandChannel = FALSE;
  673. m_bSentFileOfferPDU = TRUE;
  674. m_State = EnumWaitFileAcceptPDU;
  675. }
  676. }
  677. else
  678. {
  679. iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
  680. }
  681. delete lpNewPDU;
  682. }
  683. else
  684. {
  685. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  686. }
  687. }
  688. else
  689. {
  690. iErrorCode = (MBFT_ERROR_CODE)m_lpFile->GetLastErrorCode();
  691. //iMBFT_FILE_IO_ERROR;
  692. }
  693. if(iErrorCode != iMBFT_OK)
  694. {
  695. ReportError(iErrorType,iErrorCode,TRUE);
  696. if(m_bSentFileOfferPDU)
  697. {
  698. //If a FileOffer has been sent out, we need to send a FileStartPDU with
  699. //EOF = TRUE...
  700. TerminateCurrentSend();
  701. }
  702. else
  703. {
  704. ReportError(MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,TRUE,
  705. m_MBFTChannelID,m_CurrentFileHandle);
  706. SendNextFile();
  707. }
  708. }
  709. }
  710. BOOL MBFTPrivateSend::OnReceivedFileAcceptPDU
  711. (
  712. T120ChannelID wChannelId,
  713. T120Priority iPriority,
  714. T120UserID SenderID,
  715. LPFILEACCEPTPDU lpNewPDU,
  716. BOOL IsUniformSendData
  717. )
  718. {
  719. BOOL bReturn = FALSE;
  720. if(m_State == EnumWaitFileAcceptPDU)
  721. {
  722. if(wChannelId == m_MBFTChannelID)
  723. {
  724. if(lpNewPDU->GetFileHandle() == m_CurrentFileHandle)
  725. {
  726. TRACESEND(" Received file accept PDU from [%u] for [%u]\n",SenderID,lpNewPDU->GetFileHandle());
  727. bReturn = TRUE;
  728. for (ULONG Index = 0; Index < m_iUserCount; Index++)
  729. {
  730. if(m_lpUserArray[Index] == SenderID)
  731. {
  732. if(m_AcceptedIndex < m_iUserCount)
  733. {
  734. m_lpAcceptedUsersArray[m_AcceptedIndex++] = SenderID;
  735. }
  736. m_AcceptCount++;
  737. m_ResponseCount++;
  738. }
  739. }
  740. if(m_ResponseCount >= m_iUserCount)
  741. {
  742. m_State = EnumSendFileStartPDU;
  743. }
  744. }
  745. }
  746. }
  747. return(bReturn);
  748. }
  749. BOOL MBFTPrivateSend::OnReceivedFileRejectPDU
  750. (
  751. T120ChannelID wChannelId,
  752. T120Priority iPriority,
  753. T120UserID SenderID,
  754. LPFILEREJECTPDU lpNewPDU,
  755. BOOL IsUniformSendData
  756. )
  757. {
  758. BOOL bReturn = FALSE;
  759. if(m_State == EnumWaitFileAcceptPDU)
  760. {
  761. if(wChannelId == m_MBFTChannelID)
  762. {
  763. MBFTFILEHANDLE iFileHandle = lpNewPDU->GetFileHandle();
  764. if((iFileHandle == m_CurrentFileHandle) ||
  765. ((iFileHandle == LOWORD(_iMBFT_PROSHARE_ALL_FILES)) && m_bProshareTransfer))
  766. {
  767. TRACESEND(" Received file reject PDU from [%u] for [%u]\n",SenderID,lpNewPDU->GetFileHandle());
  768. for(ULONG Index = 0;Index < m_iUserCount;Index++)
  769. {
  770. if(m_lpUserArray[Index] == SenderID)
  771. {
  772. bReturn = TRUE;
  773. }
  774. }
  775. if(bReturn)
  776. {
  777. if(iFileHandle == m_CurrentFileHandle)
  778. {
  779. m_RejectCount++;
  780. m_ResponseCount++;
  781. }
  782. else if((iFileHandle == LOWORD(_iMBFT_PROSHARE_ALL_FILES)) && m_bProshareTransfer)
  783. {
  784. RemoveUserFromList(SenderID);
  785. }
  786. if(m_iUserCount)
  787. {
  788. if(m_ResponseCount >= m_iUserCount)
  789. {
  790. if(m_ResponseCount != m_RejectCount)
  791. {
  792. m_State = EnumSendFileStartPDU;
  793. }
  794. else
  795. {
  796. m_lpFile->Close();
  797. SendNextFile();
  798. }
  799. }
  800. }
  801. } //if bReturn
  802. }
  803. } //wChannelId == m_MBFTChannelID
  804. } //m_State == EnumWaitFileAcceptPDU
  805. return(bReturn);
  806. }
  807. BOOL MBFTPrivateSend::OnReceivedFileErrorPDU
  808. (
  809. T120ChannelID wChannelId,
  810. T120Priority iPriority,
  811. T120UserID SenderID,
  812. LPFILEERRORPDU lpNewPDU,
  813. BOOL IsUniformSendData
  814. )
  815. {
  816. BOOL bReturn = FALSE;
  817. MBFTFILEHANDLE FileHandle = lpNewPDU->GetFileHandle();
  818. if ((m_CurrentFileHandle == FileHandle) ||
  819. (m_bProshareTransfer && (LOWORD(FileHandle) == LOWORD(_iMBFT_PROSHARE_ALL_FILES))))
  820. {
  821. TRACERECEIVE(" FileErrorPDU from [%u] for [%u], ErrorCode: [%u]\n",SenderID,lpNewPDU->GetFileHandle(),lpNewPDU->GetErrorCode());
  822. if(m_bProshareTransfer)
  823. {
  824. if(m_State != EnumWaitForTermination)
  825. {
  826. if(lpNewPDU->GetErrorCode() == iMBFT_RECEIVER_ABORTED &&
  827. lpNewPDU->GetFileHandle() == LOWORD(_iMBFT_PROSHARE_ALL_FILES))
  828. {
  829. m_AbortedCount++;
  830. RemoveUserFromList(SenderID);
  831. //If the state is EnumWaitFileAcceptPDU, we don't
  832. //have an exact count of the number of recipients who accepted
  833. //the file. Therefore, we cannot make a decision on whether or not
  834. //to abort the file based on AcceptCount and AbortedCount....
  835. if(m_State != EnumWaitFileAcceptPDU)
  836. {
  837. if(m_iUserCount)
  838. {
  839. if(m_AbortedCount >= m_AcceptCount)
  840. {
  841. m_lpFile->Close();
  842. SendNextFile();
  843. }
  844. }
  845. else
  846. {
  847. m_lpFile->Close();
  848. }
  849. }
  850. else if(m_iUserCount)
  851. {
  852. //In this case, the FileErrorPDU acts as a FileRejectPDU...
  853. TRACERECEIVE(" Treating FileErrorPDU for [%u] as FileRejectPDU\n",lpNewPDU->GetFileHandle());
  854. //m_RejectCount++;
  855. //m_ResponseCount++;
  856. //In this case, response count has to be greater
  857. //because a user was just deleted!!!
  858. if(m_ResponseCount >= m_iUserCount)
  859. {
  860. if(m_ResponseCount != m_RejectCount)
  861. {
  862. m_State = EnumSendFileStartPDU;
  863. }
  864. else
  865. {
  866. SendNextFile();
  867. }
  868. }
  869. }
  870. }
  871. else if (FileHandle == m_CurrentFileHandle)
  872. {
  873. m_AbortedCount++;
  874. //If the state is EnumWaitFileAcceptPDU, we don't
  875. //have an exact count of the number of recipients who accepted
  876. //the file. Therefore, we cannot make a decision on whether or not
  877. //to abort the file based on AcceptCount and AbortedCount....
  878. if(m_State != EnumWaitFileAcceptPDU)
  879. {
  880. if(m_AbortedCount >= m_AcceptCount)
  881. {
  882. m_lpFile->Close();
  883. SendNextFile();
  884. }
  885. }
  886. else
  887. {
  888. //In this case, the FileErrorPDU acts as a FileRejectPDU...
  889. TRACERECEIVE(" Treating FileErrorPDU for [%u] as FileRejectPDU\n",lpNewPDU->GetFileHandle());
  890. m_RejectCount++;
  891. m_ResponseCount++;
  892. if(m_ResponseCount >= m_iUserCount)
  893. {
  894. if(m_ResponseCount != m_RejectCount)
  895. {
  896. m_State = EnumSendFileStartPDU;
  897. }
  898. else
  899. {
  900. SendNextFile();
  901. }
  902. }
  903. }
  904. }
  905. } //EnumWaitForTermination
  906. } //IsProshare
  907. }
  908. return(bReturn);
  909. }
  910. BOOL MBFTPrivateSend::OnReceivedNonStandardPDU
  911. (
  912. T120ChannelID wChannelID,
  913. T120Priority iPriority,
  914. T120UserID SenderID,
  915. LPNONSTANDARDPDU lpNewPDU,
  916. BOOL IsUniformSendData
  917. )
  918. {
  919. BOOL bReturn = FALSE;
  920. if(m_State != EnumWaitForTermination)
  921. {
  922. if(wChannelID == m_PrivateMBFTControlChannel)
  923. {
  924. if (! ::lstrcmpA(lpNewPDU->GetKey(), PROSHARE_FILE_END_STRING))
  925. {
  926. TRACESEND(" Received Non Standard PDU (File End Acknowledge) from [%u]\n",SenderID);
  927. FileEndAcknowledgeStruct * lpStruct = (FileEndAcknowledgeStruct *)lpNewPDU->GetDataBuffer();
  928. DBG_SAVE_FILE_LINE
  929. LPFILEENDACKNOWLEDGEPDU lpEndAckNewPDU = new FileEndAcknowledgePDU(lpStruct->m_FileHandle);
  930. if (NULL != lpEndAckNewPDU)
  931. {
  932. bReturn = OnReceivedFileEndAcknowledgePDU(wChannelID,
  933. iPriority,
  934. SenderID,
  935. lpEndAckNewPDU,
  936. IsUniformSendData);
  937. delete lpEndAckNewPDU;
  938. }
  939. }
  940. else if (! ::lstrcmpA(lpNewPDU->GetKey(), PROSHARE_CHANNEL_LEAVE_STRING))
  941. {
  942. TRACESEND(" Received Non Standard PDU (Channel Leave) from [%u]\n",SenderID);
  943. ChannelLeaveStruct * lpStruct = (ChannelLeaveStruct *)lpNewPDU->GetDataBuffer();
  944. DBG_SAVE_FILE_LINE
  945. LPCHANNELLEAVEPDU lpLeaveNewPDU = new ChannelLeavePDU(lpStruct->m_ChannelID,lpStruct->m_ErrorCode);
  946. if (NULL != lpLeaveNewPDU)
  947. {
  948. bReturn = OnReceivedChannelLeavePDU(wChannelID,
  949. iPriority,
  950. SenderID,
  951. lpLeaveNewPDU,
  952. IsUniformSendData);
  953. delete lpLeaveNewPDU;
  954. }
  955. }
  956. else
  957. {
  958. TRACE("*** Unknown Non Standard PDU received on [%u] *** \n",wChannelID);
  959. }
  960. }
  961. }
  962. return(bReturn);
  963. }
  964. BOOL MBFTPrivateSend::OnReceivedFileEndAcknowledgePDU
  965. (
  966. T120ChannelID wChannelId,
  967. T120Priority iPriority,
  968. T120UserID SenderID,
  969. LPFILEENDACKNOWLEDGEPDU lpNewPDU,
  970. BOOL IsUniformSendData
  971. )
  972. {
  973. BOOL bReturn = FALSE;
  974. if(m_State == EnumWaitFileEndAcknowledgePDU)
  975. {
  976. if(wChannelId == m_PrivateMBFTControlChannel)
  977. {
  978. if(lpNewPDU->GetFileHandle() == m_CurrentFileHandle)
  979. {
  980. TRACESEND(" Received file end acknowledge PDU from [%u] for [%u]\n",SenderID,lpNewPDU->GetFileHandle());
  981. bReturn = TRUE;
  982. for (ULONG Index = 0; Index < m_AcceptedIndex; Index++)
  983. {
  984. if(m_lpAcceptedUsersArray[Index] == SenderID)
  985. {
  986. m_AcknowledgeCount++;
  987. }
  988. }
  989. if(m_AcknowledgeCount >= m_AcceptCount)
  990. {
  991. SendNextFile();
  992. }
  993. }
  994. }
  995. }
  996. return(bReturn);
  997. }
  998. BOOL MBFTPrivateSend::OnReceivedChannelLeavePDU
  999. (
  1000. T120ChannelID wChannelId,
  1001. T120Priority iPriority,
  1002. T120UserID SenderID,
  1003. LPCHANNELLEAVEPDU lpNewPDU,
  1004. BOOL IsUniformSendData
  1005. )
  1006. {
  1007. BOOL bReturn = FALSE;
  1008. if(m_State == EnumSendFileStartPDU || m_State == EnumSendFileDataPDU ||
  1009. m_State == EnumWaitFileEndAcknowledgePDU)
  1010. {
  1011. if(lpNewPDU->GetChannelID() == m_PrivateMBFTDataChannel)
  1012. {
  1013. bReturn = TRUE;
  1014. TRACESEND(" Received Channel Leave PDU from [%u] for [%u], CurrentFile [%u]\n",
  1015. SenderID,lpNewPDU->GetChannelID(),m_CurrentFileHandle);
  1016. for (ULONG Index = 0; Index < m_AcceptedIndex; Index++)
  1017. {
  1018. if(m_lpAcceptedUsersArray[Index] == SenderID)
  1019. {
  1020. m_AcknowledgeCount++;
  1021. }
  1022. }
  1023. if(m_State == EnumWaitFileEndAcknowledgePDU)
  1024. {
  1025. if(m_AcknowledgeCount >= m_AcceptCount)
  1026. {
  1027. SendNextFile();
  1028. }
  1029. }
  1030. }
  1031. }
  1032. return(bReturn);
  1033. }
  1034. void MBFTPrivateSend::SendFileStartPDU(void)
  1035. {
  1036. if(!m_bAbortAllFiles)
  1037. {
  1038. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  1039. MBFT_ERROR_TYPES iErrorType = MBFT_TRANSIENT_ERROR;
  1040. LONG lCurrentPosition = m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
  1041. FILE_HEADER_INFO fileHeaderInfo;
  1042. fileHeaderInfo.fileName = (LPSTR)GetFileNameFromPath(m_pszCurrentFilePath);
  1043. fileHeaderInfo.fileSize = m_CurrentFileSize;
  1044. fileHeaderInfo.pduType = T127_FILE_START;
  1045. GetFileHeaderSize(&fileHeaderInfo);
  1046. int iSizeofFileHeader = fileHeaderInfo.pduSize + sizeof(T127_FILE_START_DATA_BLOCK_HEADER);
  1047. int iBytesRead = m_lpFile->Read(m_lpDataBuffer + iSizeofFileHeader ,m_MaxDataLength);
  1048. m_bSendingFile = TRUE;
  1049. if(iBytesRead != -1)
  1050. {
  1051. BOOL bIsEOF = (m_lTotalBytesRead + iBytesRead) >= m_CurrentFileSize;
  1052. LPFILESTARTPDU lpNewPDU = NULL;
  1053. if(!iBytesRead)
  1054. {
  1055. DBG_SAVE_FILE_LINE
  1056. lpNewPDU = new FileStartPDU(m_lpDataBuffer,
  1057. fileHeaderInfo.fileName, // GetFileNameFromPath(m_pszCurrentFilePath),
  1058. LOWORD(m_CurrentFileHandle),
  1059. m_CurrentFileSize,
  1060. m_CurrentDateTime,
  1061. m_lpDataBuffer,
  1062. 0,
  1063. bIsEOF);
  1064. }
  1065. else
  1066. {
  1067. if(!m_bCompressFiles)
  1068. {
  1069. DBG_SAVE_FILE_LINE
  1070. lpNewPDU = new FileStartPDU(m_lpDataBuffer,
  1071. fileHeaderInfo.fileName, // GetFileNameFromPath(m_pszCurrentFilePath),
  1072. LOWORD(m_CurrentFileHandle),
  1073. m_CurrentFileSize,
  1074. m_CurrentDateTime,
  1075. m_lpDataBuffer,
  1076. iBytesRead,
  1077. bIsEOF);
  1078. }
  1079. else
  1080. {
  1081. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  1082. }
  1083. }
  1084. if(iErrorCode == iMBFT_OK)
  1085. {
  1086. if(lpNewPDU)
  1087. {
  1088. if(lpNewPDU->Encode())
  1089. {
  1090. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTDataChannel,
  1091. APPLET_LOW_PRIORITY,
  1092. (LPBYTE)lpNewPDU->GetBuffer(),
  1093. lpNewPDU->GetBufferLength()))
  1094. {
  1095. TRACESEND(" Sent file start PDU for [%ld] on [%u], EOF = [%d]\n",
  1096. m_CurrentFileHandle, m_PrivateMBFTDataChannel, bIsEOF);
  1097. m_lTotalBytesRead += iBytesRead;
  1098. m_SentFileStartPDU = TRUE;
  1099. SendNotificationMessage(iMBFT_FILE_SEND_BEGIN);
  1100. if(bIsEOF)
  1101. {
  1102. m_lpFile->Close();
  1103. if(!m_bEOFAcknowledge)
  1104. {
  1105. SendNextFile();
  1106. }
  1107. else
  1108. {
  1109. TRACESEND(" Waiting for End of File ack PDU\n");
  1110. m_State = EnumWaitFileEndAcknowledgePDU;
  1111. }
  1112. }
  1113. else
  1114. {
  1115. m_State = EnumSendFileDataPDU;
  1116. }
  1117. }
  1118. else
  1119. {
  1120. m_lpFile->Seek(lCurrentPosition,CMBFTFile::SeekMode::SeekFromBegin);
  1121. }
  1122. }
  1123. else
  1124. {
  1125. iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
  1126. }
  1127. } //if(lpNewPDU)
  1128. else
  1129. {
  1130. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  1131. }
  1132. } //if iErrorCode == iMBFT_OK
  1133. if(lpNewPDU)
  1134. {
  1135. lpNewPDU->NULLDataBuffer();
  1136. delete lpNewPDU;
  1137. }
  1138. } //If bytes read...
  1139. else
  1140. {
  1141. iErrorCode = (MBFT_ERROR_CODE)m_lpFile->GetLastErrorCode();
  1142. //iMBFT_FILE_IO_ERROR;
  1143. }
  1144. if(iErrorCode != iMBFT_OK)
  1145. {
  1146. ReportError(iErrorType,iErrorCode,TRUE);
  1147. ReportSenderError(iErrorType,iErrorCode);
  1148. TerminateCurrentSend();
  1149. }
  1150. }
  1151. else
  1152. {
  1153. TerminateCurrentSend();
  1154. }
  1155. }
  1156. void MBFTPrivateSend::SendNotificationMessage
  1157. (
  1158. int iProgress,
  1159. T120UserID iUserID,
  1160. MBFTFILEHANDLE hFileHandle
  1161. )
  1162. {
  1163. T120UserID id = iUserID ? iUserID : m_MBFTChannelID;
  1164. DBG_SAVE_FILE_LINE
  1165. m_lpParentEngine->SafePostNotifyMessage(
  1166. new FileTransmitMsg(m_EventHandle,
  1167. hFileHandle ? hFileHandle : m_CurrentFileHandle,
  1168. m_CurrentFileSize,
  1169. m_lTotalBytesRead,
  1170. iProgress,
  1171. id));
  1172. }
  1173. void MBFTPrivateSend::TerminateCurrentSend(void)
  1174. {
  1175. m_State = EnumTerminateCurrentSend;
  1176. ReportError(MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,TRUE,
  1177. m_MBFTChannelID,m_CurrentFileHandle);
  1178. //We don't care about compression in this case because the buffer is NULL....
  1179. DBG_SAVE_FILE_LINE
  1180. LPFILEDATAPDU lpNewPDU = new FileDataPDU(m_lpDataBuffer,LOWORD(m_CurrentFileHandle),m_lpDataBuffer,0, FALSE, TRUE);
  1181. if(lpNewPDU)
  1182. {
  1183. if(lpNewPDU->Encode())
  1184. {
  1185. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTDataChannel,
  1186. APPLET_LOW_PRIORITY,
  1187. (LPBYTE)lpNewPDU->GetBuffer(),
  1188. lpNewPDU->GetBufferLength()))
  1189. {
  1190. m_lpFile->Close();
  1191. SendNextFile();
  1192. }
  1193. }
  1194. lpNewPDU->NULLDataBuffer();
  1195. delete lpNewPDU;
  1196. }
  1197. }
  1198. void MBFTPrivateSend::SendFileDataPDU(void)
  1199. {
  1200. LONG lCurrentPosition = -1;
  1201. LPFILEDATAPDU lpNewPDU = NULL;
  1202. int iBytesRead,Index;
  1203. BOOL bIsEOF = FALSE,bTerminate = FALSE;
  1204. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  1205. MBFT_ERROR_TYPES iErrorType = MBFT_TRANSIENT_ERROR;
  1206. if(!m_bAbortFileSend)
  1207. {
  1208. for(Index = 0;(Index < _MAX_SEND_PACKETS) && !bTerminate;Index++)
  1209. {
  1210. lCurrentPosition = m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
  1211. iBytesRead = m_lpFile->Read(m_lpDataBuffer + sizeof(T127_FILE_DATA_HEADER),m_MaxDataLength);
  1212. if(iBytesRead != -1)
  1213. {
  1214. BOOL bDataSent = FALSE;
  1215. bIsEOF = m_lpFile->GetIsEOF();
  1216. if(!m_bCompressFiles)
  1217. {
  1218. DBG_SAVE_FILE_LINE
  1219. lpNewPDU = new FileDataPDU(m_lpDataBuffer,
  1220. LOWORD(m_CurrentFileHandle),
  1221. m_lpDataBuffer,iBytesRead,bIsEOF,
  1222. FALSE);
  1223. }
  1224. else
  1225. {
  1226. // MSFT error - no compression
  1227. }
  1228. if(lpNewPDU)
  1229. {
  1230. if(lpNewPDU->Encode())
  1231. {
  1232. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTDataChannel,
  1233. APPLET_LOW_PRIORITY,
  1234. (LPBYTE)lpNewPDU->GetBuffer(),
  1235. lpNewPDU->GetBufferLength()))
  1236. {
  1237. TRACESEND(" Sent file data PDU on [%u], EOF = [%d], BufferSize = [%d]\n",m_PrivateMBFTDataChannel,bIsEOF,lpNewPDU->GetBufferLength());
  1238. //m_lTotalBytesRead += iBytesRead;
  1239. m_lTotalBytesRead = m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
  1240. bDataSent = TRUE;
  1241. SendNotificationMessage(iMBFT_FILE_SEND_PROGRESS);
  1242. if(bIsEOF)
  1243. {
  1244. m_lpFile->Close();
  1245. if(!m_bEOFAcknowledge)
  1246. {
  1247. SendNextFile();
  1248. }
  1249. else
  1250. {
  1251. TRACESEND(" Waiting for End of File ack PDU\n");
  1252. m_State = EnumWaitFileEndAcknowledgePDU;
  1253. }
  1254. bTerminate = TRUE;
  1255. }
  1256. }
  1257. if(!bDataSent)
  1258. {
  1259. m_lpFile->Seek(lCurrentPosition,CMBFTFile::SeekMode::SeekFromBegin);
  1260. bTerminate = TRUE;
  1261. }
  1262. }
  1263. else
  1264. {
  1265. iErrorCode = iMBFT_ASN1_ENCODING_ERROR;
  1266. break;
  1267. }
  1268. lpNewPDU->NULLDataBuffer();
  1269. delete lpNewPDU;
  1270. }
  1271. else
  1272. {
  1273. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  1274. break;
  1275. }
  1276. }
  1277. else
  1278. {
  1279. iErrorCode = (MBFT_ERROR_CODE)m_lpFile->GetLastErrorCode();
  1280. //iMBFT_FILE_IO_ERROR;
  1281. break;
  1282. }
  1283. } //for loop
  1284. }
  1285. else
  1286. {
  1287. TerminateCurrentSend();
  1288. }
  1289. if(iErrorCode != iMBFT_OK)
  1290. {
  1291. ReportError(iErrorType,iErrorCode,TRUE);
  1292. ReportSenderError(iErrorType,iErrorCode);
  1293. TerminateCurrentSend();
  1294. }
  1295. }
  1296. void MBFTPrivateSend::RemoveFileFromList
  1297. (
  1298. MBFTFILEHANDLE hFile
  1299. )
  1300. {
  1301. if (hFile == m_CurrentFileHandle)
  1302. {
  1303. ReportError(MBFT_PERMANENT_ERROR,iMBFT_NO_MORE_FILES,TRUE);
  1304. TerminateSendSession();
  1305. }
  1306. }
  1307. BOOL MBFTPrivateSend::RemoveUserFromAcceptedList
  1308. (
  1309. T120UserID iUserID
  1310. )
  1311. {
  1312. BOOL bUserRemoved = FALSE;
  1313. for (ULONG Index = 1; Index <= m_AcceptedIndex; Index++)
  1314. {
  1315. if(m_lpAcceptedUsersArray[Index - 1] == iUserID)
  1316. {
  1317. bUserRemoved = TRUE;
  1318. if(Index != m_AcceptedIndex)
  1319. {
  1320. CopyMemory(&m_lpAcceptedUsersArray[Index - 1],&m_lpAcceptedUsersArray[Index],
  1321. (m_AcceptedIndex - Index) * sizeof(UserID));
  1322. }
  1323. m_AcceptedIndex--;
  1324. }
  1325. }
  1326. return(bUserRemoved);
  1327. }
  1328. BOOL MBFTPrivateSend::RemoveUserFromList
  1329. (
  1330. T120UserID iUserID
  1331. )
  1332. {
  1333. BOOL bUserRemoved = FALSE;
  1334. for (ULONG Index = 1; Index <= m_iUserCount; Index++)
  1335. {
  1336. if(m_lpUserArray[Index - 1] == iUserID)
  1337. {
  1338. bUserRemoved = TRUE;
  1339. if(Index != m_iUserCount)
  1340. {
  1341. CopyMemory(&m_lpUserArray[Index - 1],&m_lpUserArray[Index],
  1342. (m_iUserCount - Index) * sizeof(UserID));
  1343. }
  1344. m_iUserCount--;
  1345. }
  1346. }
  1347. if(bUserRemoved)
  1348. {
  1349. if(!m_iUserCount)
  1350. {
  1351. ReportError(MBFT_PERMANENT_ERROR,iMBFT_NO_MORE_RECIPIENTS,TRUE);
  1352. if(m_State == EnumSendFileDataPDU || m_State == EnumSendFileOfferPDU ||
  1353. m_State == EnumWaitFileAcceptPDU)
  1354. {
  1355. if(m_lpFile)
  1356. {
  1357. m_lpFile->Close();
  1358. }
  1359. if(m_State == EnumSendFileDataPDU)
  1360. {
  1361. SendNotificationMessage(iMBFT_FILE_SEND_END);
  1362. }
  1363. }
  1364. TerminateSendSession();
  1365. }
  1366. }
  1367. return(bUserRemoved);
  1368. }
  1369. void MBFTPrivateSend::OnControlNotification
  1370. (
  1371. MBFTFILEHANDLE hFile,
  1372. FileTransferControlMsg::FileTransferControl iControlCommand,
  1373. LPCSTR lpszDirectory,
  1374. LPCSTR lpszFileName
  1375. )
  1376. {
  1377. if(iControlCommand == FileTransferControlMsg::EnumAbortFile ||
  1378. iControlCommand == FileTransferControlMsg::EnumConductorAbortFile)
  1379. {
  1380. if(m_bOKToDisbandChannel)
  1381. {
  1382. if(hFile == _iMBFT_PROSHARE_ALL_FILES /*&& m_bProshareTransfer*/)
  1383. {
  1384. //Fix to ensure a iMBFT_SENDER_ABORTED notification if sender aborts way too early...
  1385. ReportError(MBFT_INFORMATIVE_ERROR,
  1386. (iControlCommand == FileTransferControlMsg::EnumAbortFile) ?
  1387. iMBFT_SENDER_ABORTED :
  1388. iMBFT_CONDUCTOR_ABORTED,
  1389. TRUE,
  1390. m_MBFTChannelID,
  1391. _iMBFT_PROSHARE_ALL_FILES);
  1392. UnInitialize();
  1393. }
  1394. else
  1395. {
  1396. RemoveFileFromList(hFile);
  1397. }
  1398. }
  1399. else if(!m_bUnInitializing)
  1400. {
  1401. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  1402. {
  1403. AbortAllFiles();
  1404. }
  1405. else if(hFile == m_CurrentFileHandle)
  1406. {
  1407. AbortCurrentFile();
  1408. }
  1409. }
  1410. }
  1411. }
  1412. void MBFTPrivateSend::AbortAllFiles(void)
  1413. {
  1414. AbortCurrentFile();
  1415. m_bAbortAllFiles = TRUE;
  1416. }
  1417. void MBFTPrivateSend::AbortCurrentFile(void)
  1418. {
  1419. if(m_bSendingFile)
  1420. {
  1421. m_bAbortFileSend = TRUE;
  1422. }
  1423. }
  1424. void MBFTPrivateSend::SendNextFile(void)
  1425. {
  1426. // Notify the ui if some receivers didn't accept the previous file
  1427. if(m_AbortedCount)
  1428. {
  1429. // All the receivers aborted the FT, this is the same as the sender canceling FT
  1430. ReportError(MBFT_PERMANENT_ERROR,
  1431. m_AbortedCount >= m_AcceptCount ? iMBFT_SENDER_ABORTED : iMBFT_MULT_RECEIVER_ABORTED,
  1432. TRUE);
  1433. }
  1434. if(m_RejectCount)
  1435. {
  1436. // If we just had one FT an it rejected we say that there was a problem sending the file
  1437. // If we had more receivers we will use the receiver aborted message
  1438. ReportError(MBFT_PERMANENT_ERROR,
  1439. m_AcceptCount == 0 ? iMBFT_RECEIVER_REJECTED : iMBFT_MULT_RECEIVER_ABORTED,
  1440. TRUE);
  1441. }
  1442. // We are sending or the receiver Rejected before we start sending
  1443. if(m_bSendingFile || m_RejectCount)
  1444. {
  1445. SendNotificationMessage(iMBFT_FILE_SEND_END);
  1446. }
  1447. m_bSendingFile = FALSE;
  1448. m_bAbortFileSend = FALSE;
  1449. TerminateSendSession();
  1450. }
  1451. void MBFTPrivateSend::OnPeerDeletedNotification
  1452. (
  1453. CPeerData *lpPeerData
  1454. )
  1455. {
  1456. if(m_State != EnumWaitForTermination)
  1457. {
  1458. if(RemoveUserFromList(lpPeerData->GetUserID()))
  1459. {
  1460. if(m_iUserCount)
  1461. {
  1462. if(m_State == EnumWaitFileAcceptPDU ||
  1463. m_State == EnumWaitChannelResponsePDU)
  1464. {
  1465. //m_RejectCount++;
  1466. //m_ResponseCount++;
  1467. if(m_ResponseCount >= m_iUserCount)
  1468. {
  1469. if(m_State == EnumWaitFileAcceptPDU)
  1470. {
  1471. if(m_ResponseCount != m_RejectCount)
  1472. {
  1473. m_State = EnumSendFileStartPDU;
  1474. }
  1475. else
  1476. {
  1477. SendNextFile();
  1478. }
  1479. }
  1480. else if(m_State == EnumWaitChannelResponsePDU)
  1481. {
  1482. if(!m_bProshareTransfer)
  1483. {
  1484. m_State = EnumSendFileOfferPDU;
  1485. }
  1486. else
  1487. {
  1488. m_State = EnumSendNonStandardPDU;
  1489. }
  1490. }
  1491. } //m_ResponseCount >= m_iUserCount
  1492. }
  1493. else if ((m_State == EnumWaitFileEndAcknowledgePDU) || (m_State == EnumSendFileDataPDU))
  1494. {
  1495. if(RemoveUserFromAcceptedList(lpPeerData->GetUserID()))
  1496. {
  1497. m_AcknowledgeCount++;
  1498. }
  1499. if(m_AcknowledgeCount >= m_AcceptCount)
  1500. {
  1501. SendNextFile();
  1502. }
  1503. }
  1504. } //UserCount
  1505. } //RemoveUserFromList
  1506. } //EnumWaitForTermination
  1507. }