Source code of Windows XP (NT5)
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.

1932 lines
61 KiB

  1. /* file: mbftRecv.cpp */
  2. #include "mbftpch.h"
  3. #include "mbftrecv.hpp"
  4. #include "fileio.hpp"
  5. #include "messages.hpp"
  6. #include "mbftper.h"
  7. extern TCHAR s_szMSFT[64];
  8. extern HRESULT GetRecvFolder(LPTSTR pszInFldr, LPTSTR pszOutFldr);
  9. extern void OnChangeFolder(void);
  10. extern int MyLoadString(UINT idStr, LPTSTR pszDstStr, LPTSTR pszElement);
  11. LPTSTR GetRootDirPath(LPTSTR pszDirPath, LPTSTR pszRootDirPath, int nSize);
  12. MBFTPrivateReceive::MBFTPrivateReceive
  13. (
  14. LPMBFTENGINE lpParentEngine,
  15. MBFTEVENTHANDLE EventHandle,
  16. T120ChannelID wControlChannel,
  17. T120ChannelID wDataChannel
  18. )
  19. :
  20. MBFTSession(lpParentEngine, EventHandle, MBFT_PRIVATE_RECV_TYPE),
  21. m_PrivateMBFTControlChannel(wControlChannel),
  22. m_PrivateMBFTDataChannel(wDataChannel),
  23. m_MBFTControlSenderID(0),
  24. m_MBFTDataSenderID(0),
  25. m_ProshareSenderID(0),
  26. m_LocalMBFTUserID(0),
  27. m_bProshareTransfer(FALSE),
  28. m_JoinedToDataChannel(FALSE),
  29. m_bOKToLeaveDataChannel(FALSE),
  30. m_CurrentReceiveEvent(NULL),
  31. m_bEventEndPosted(FALSE),
  32. m_CurrentAcceptHandle(0),
  33. m_CurrentRejectHandle(0),
  34. m_CurrentFileEndHandle(0),
  35. m_PreviousRejectState(EnumIdleNotInitialized),
  36. m_State(EnumWaitAdmitControlChannel)
  37. {
  38. m_PrivateMBFTDataChannelList.Append(m_PrivateMBFTDataChannel);
  39. }
  40. MBFTPrivateReceive::~MBFTPrivateReceive(void)
  41. {
  42. m_ReceiveList.DeleteAll();
  43. }
  44. void MBFTPrivateReceive::JoinControlChannel(void)
  45. {
  46. if(m_lpParentEngine->MCSChannelJoinRequest(m_PrivateMBFTControlChannel))
  47. {
  48. m_State = EnumWaitJoinControlChannel;
  49. }
  50. else
  51. {
  52. m_State = EnumInitializationFailed;
  53. }
  54. }
  55. void MBFTPrivateReceive::JoinDataChannel(void)
  56. {
  57. if(m_lpParentEngine->MCSChannelJoinRequest(m_PrivateMBFTDataChannel))
  58. {
  59. if(m_State == EnumWaitAdmitDataChannelIndication)
  60. {
  61. m_State = EnumWaitJoinDataChannel;
  62. }
  63. }
  64. else
  65. {
  66. m_State = EnumInitializationFailed;
  67. }
  68. }
  69. BOOL MBFTPrivateReceive::OnMCSChannelJoinConfirm
  70. (
  71. T120ChannelID wChannelID,
  72. BOOL bSuccess
  73. )
  74. {
  75. BOOL bReturn = FALSE;
  76. if(m_State == EnumWaitJoinControlChannel)
  77. {
  78. if(wChannelID == m_PrivateMBFTControlChannel)
  79. {
  80. bReturn = TRUE;
  81. m_State = bSuccess ? EnumWaitAdmitDataChannelIndication :
  82. EnumInitializationFailed;
  83. // data channel admit indication may come earlier than this state change.
  84. // look for unserviced channel admit indication
  85. if (EnumWaitAdmitDataChannelIndication == m_State)
  86. {
  87. UINT_PTR chid_uid;
  88. m_AdmittedChannelQueue.Reset();
  89. while (0 != (chid_uid = m_AdmittedChannelQueue.Iterate()))
  90. {
  91. if (m_PrivateMBFTDataChannelList.Find(LOWORD(chid_uid)))
  92. {
  93. OnMCSChannelAdmitIndication(LOWORD(chid_uid), HIWORD(chid_uid));
  94. m_AdmittedChannelQueue.Remove(chid_uid);
  95. break;
  96. }
  97. }
  98. }
  99. }
  100. }
  101. else if(m_State == EnumWaitJoinDataChannel || m_State == EnumWaitRejoinDataChannel)
  102. {
  103. if(m_PrivateMBFTDataChannelList.Find(wChannelID))
  104. {
  105. bReturn = TRUE;
  106. if(bSuccess)
  107. {
  108. m_JoinedToDataChannel = TRUE;
  109. if(m_State == EnumWaitJoinDataChannel)
  110. {
  111. m_State = EnumWaitSendChannelResponsePDU;
  112. }
  113. else if(m_State == EnumWaitRejoinDataChannel)
  114. {
  115. TRACERECEIVE(" Rejoined Data Channel [%u]\n",wChannelID);
  116. if(m_CurrentReceiveEvent)
  117. {
  118. SendFileAcceptPDU((unsigned)m_CurrentReceiveEvent->m_hFile);
  119. m_CurrentReceiveEvent->m_State = EnumWaitFileStartPDU;
  120. }
  121. else
  122. {
  123. TRACE(" *** WARNING: Receive Event deleted before Data Channel was rejoined! ***\n");
  124. }
  125. //m_State = EnumWaitFileOfferPDU;
  126. }
  127. }
  128. else
  129. {
  130. m_State = EnumInitializationFailed;
  131. }
  132. }
  133. }
  134. return(bReturn);
  135. }
  136. void MBFTPrivateReceive::UnInitialize
  137. (
  138. BOOL bIsShutDown
  139. )
  140. {
  141. if(m_State != EnumWaitForTermination)
  142. {
  143. m_State = EnumWaitForTermination;
  144. MBFTReceiveSubEvent * lpReceive;
  145. m_ReceiveList.Reset();
  146. while (NULL != (lpReceive = m_ReceiveList.Iterate()))
  147. {
  148. if(!lpReceive->m_UserAccepted)
  149. {
  150. lpReceive->m_lpFile->DeleteFile();
  151. }
  152. }
  153. m_PrivateMBFTDataChannelList.Clear();
  154. if(!bIsShutDown)
  155. {
  156. DBG_SAVE_FILE_LINE
  157. m_lpParentEngine->SafePostMessage(new DeleteSessionMsg(this));
  158. if(!m_bEventEndPosted)
  159. {
  160. DBG_SAVE_FILE_LINE
  161. m_lpParentEngine->SafePostNotifyMessage(
  162. new FileEventEndNotifyMsg(m_EventHandle));
  163. m_bEventEndPosted = TRUE;
  164. }
  165. }
  166. }
  167. }
  168. MBFTReceiveSubEvent::MBFTReceiveSubEvent
  169. (
  170. MBFTFILEHANDLE hFile,
  171. LONG FileSize,
  172. LPCSTR lpszFileName,
  173. time_t FileDateTime,
  174. T120UserID SenderID,
  175. BOOL bIsBroadcast,
  176. BOOL bIsCompressed,
  177. BOOL bEOFAcknowledge
  178. )
  179. :
  180. m_bIsBroadcast(bIsBroadcast),
  181. m_hFile(MAKELONG(hFile,SenderID)),
  182. m_FileSize(FileSize),
  183. m_FileDateTime(FileDateTime),
  184. m_TotalBytesReceived(0),
  185. m_cbRecvLastNotify(0),
  186. m_bFileCompressed(bIsCompressed),
  187. m_bEOFAcknowledge(bEOFAcknowledge),
  188. m_SenderID(SenderID),
  189. m_lpFile(NULL),
  190. m_UserAccepted(FALSE)
  191. {
  192. if(lpszFileName)
  193. {
  194. ::lstrcpynA(m_szFileName,lpszFileName,sizeof(m_szFileName));
  195. }
  196. else
  197. {
  198. m_szFileName[0] = '\0';
  199. }
  200. m_szFileDirectory[0] = '\0';
  201. m_State = (! bIsBroadcast) ? MBFTPrivateReceive::EnumWaitUserConfirmation :
  202. MBFTPrivateReceive::EnumWaitFileStartPDU;
  203. }
  204. BOOL MBFTReceiveSubEvent::Init(void)
  205. {
  206. DBG_SAVE_FILE_LINE
  207. m_lpFile = new CMBFTFile;
  208. return(m_lpFile != NULL);
  209. }
  210. MBFTReceiveSubEvent::~MBFTReceiveSubEvent(void)
  211. {
  212. if(m_lpFile)
  213. {
  214. // if the file wasn't completely received, delete it
  215. if (m_TotalBytesReceived < m_FileSize)
  216. m_lpFile->Close(FALSE);
  217. delete m_lpFile;
  218. }
  219. }
  220. BOOL MBFTReceiveSubEvent::IsEqual
  221. (
  222. MBFTReceiveSubEvent *lpObject
  223. )
  224. {
  225. BOOL bReturn = FALSE;
  226. if(!lpObject->m_SenderID || !m_SenderID)
  227. {
  228. bReturn = (lpObject->m_hFile == (MBFTFILEHANDLE)MAKELONG(m_hFile, lpObject->m_SenderID));
  229. }
  230. else
  231. {
  232. bReturn = (lpObject->m_hFile == m_hFile) && (lpObject->m_SenderID == m_SenderID);
  233. }
  234. return(bReturn);
  235. }
  236. BOOL MBFTPrivateReceive::OnReceivedFileOfferPDU
  237. (
  238. T120ChannelID wChannelID,
  239. T120Priority iPriority,
  240. T120UserID SenderID,
  241. T120NodeID NodeID,
  242. LPFILEOFFERPDU lpFileOfferPDU,
  243. BOOL IsUniformSendData
  244. )
  245. {
  246. BOOL bReturn = FALSE;
  247. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  248. MBFT_ERROR_TYPES iErrorType = MBFT_INFORMATIVE_ERROR;
  249. if(wChannelID == m_PrivateMBFTControlChannel)
  250. {
  251. bReturn = TRUE;
  252. if(m_State == EnumWaitFileOfferPDU)
  253. {
  254. // Sanity checking
  255. DWORD res;
  256. // Windows 95 can't take NULL pointers for these
  257. DWORD SecPerCluster, BytePerSector, FreeCluster, TotalFreeCluster;
  258. TCHAR szDirPath[MAX_PATH];
  259. TCHAR szRootDirPath[MAX_PATH], *pszRootDir;
  260. ::GetRecvFolder(NULL, szDirPath);
  261. res = GetFileAttributes(szDirPath);
  262. if ((0xffffffff == res)||!(res | FILE_ATTRIBUTE_DIRECTORY))
  263. { // invalid directory name
  264. iErrorCode = iMBFT_INVALID_PATH;
  265. goto ERRORPROCESS;
  266. }
  267. pszRootDir = GetRootDirPath(szDirPath, szRootDirPath, MAX_PATH);
  268. if (GetDiskFreeSpace(pszRootDir, &SecPerCluster,
  269. &BytePerSector, &FreeCluster, &TotalFreeCluster))
  270. {
  271. if (!(BytePerSector && SecPerCluster))
  272. {
  273. WARNING_OUT(("BytePerSector %d, SecPerCluster %d\n", BytePerSector,
  274. SecPerCluster));
  275. }
  276. else if ((ULONG)lpFileOfferPDU->GetFileSize()/BytePerSector/SecPerCluster + 1 > FreeCluster)
  277. { // not enough space to save the file
  278. iErrorCode = iMBFT_DIRECTORY_FULL_ERROR;
  279. goto ERRORPROCESS;
  280. }
  281. }
  282. else
  283. {
  284. ERROR_OUT(("GetDiskSpace Failed, error %d\n", GetLastError()));
  285. }
  286. BOOL bAckRequired = lpFileOfferPDU->GetAcknowledge();
  287. m_bOKToLeaveDataChannel = bAckRequired;
  288. //Change compression handling later -- for now, we assume that a Proshare send is
  289. //always compressed....
  290. BOOL bEOFAcknowledge = FALSE;
  291. CPeerList *pPeerList = m_lpParentEngine->GetPeerList();
  292. CPeerData *lpPeer;
  293. pPeerList->Reset();
  294. while (NULL != (lpPeer = pPeerList->Iterate()))
  295. {
  296. if(lpPeer->GetUserID() == SenderID)
  297. {
  298. bEOFAcknowledge = lpPeer->GetEOFAcknowledge();
  299. break;
  300. }
  301. }
  302. DBG_SAVE_FILE_LINE
  303. MBFTReceiveSubEvent * lpNewReceive = new MBFTReceiveSubEvent(lpFileOfferPDU->GetFileHandle(),
  304. lpFileOfferPDU->GetFileSize(),
  305. lpFileOfferPDU->GetFileName(),
  306. lpFileOfferPDU->GetFileDateTime(),
  307. SenderID,
  308. !bAckRequired,
  309. lpFileOfferPDU->GetCompressionFlags() & _MBFT_FILE_COMPRESSED,
  310. bEOFAcknowledge);
  311. if(lpNewReceive)
  312. {
  313. if(lpNewReceive->Init())
  314. {
  315. m_ReceiveList.Append(lpNewReceive);
  316. // lonchanc: how can you use static char szTemp[] here???
  317. char szRecvDir[MAX_PATH];
  318. ::GetRecvFolder(NULL, szRecvDir);
  319. if(lpNewReceive->m_lpFile->Create(szRecvDir, lpNewReceive->m_szFileName))
  320. {
  321. DBG_SAVE_FILE_LINE
  322. m_lpParentEngine->SafePostNotifyMessage(
  323. new FileOfferNotifyMsg(m_EventHandle,
  324. SenderID,
  325. NodeID,
  326. lpNewReceive->m_hFile,
  327. lpNewReceive->m_lpFile->GetFileName(),
  328. lpNewReceive->m_FileSize,
  329. lpNewReceive->m_FileDateTime,
  330. bAckRequired));
  331. }
  332. else
  333. {
  334. iErrorCode = iMBFT_FILE_ACCESS_DENIED;
  335. goto ERRORPROCESS;
  336. }
  337. }
  338. else
  339. {
  340. delete lpNewReceive;
  341. }
  342. }
  343. }
  344. else if(m_State == EnumWaitChannelDisband)
  345. {
  346. SendFileRejectPDU(lpFileOfferPDU->GetFileHandle());
  347. }
  348. }
  349. return(bReturn);
  350. ERRORPROCESS:
  351. ReportError(NULL,iErrorType,iErrorCode, TRUE, 0,
  352. lpFileOfferPDU->GetFileName(),
  353. lpFileOfferPDU->GetFileSize());
  354. SendFileRejectPDU(lpFileOfferPDU->GetFileHandle());
  355. return (bReturn);
  356. }
  357. BOOL MBFTPrivateReceive::OnReceivedFileStartPDU
  358. (
  359. T120ChannelID wChannelId,
  360. T120Priority iPriority,
  361. T120UserID SenderID,
  362. LPFILESTARTPDU lpFileStartPDU,
  363. BOOL IsUniformSendData
  364. )
  365. {
  366. BOOL bReturn = FALSE;
  367. MBFTReceiveSubEvent * lpReceiveEvent;
  368. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  369. MBFT_ERROR_TYPES iErrorType = MBFT_INFORMATIVE_ERROR;
  370. if (m_PrivateMBFTDataChannelList.Find(wChannelId))
  371. {
  372. if(m_State != EnumWaitForTermination && m_State != EnumWaitChannelDisband)
  373. {
  374. bReturn = TRUE;
  375. MBFTReceiveSubEvent TempReceive(lpFileStartPDU->GetFileHandle(),0,NULL,0,SenderID,FALSE,m_bProshareTransfer,FALSE);
  376. lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  377. if(lpReceiveEvent)
  378. {
  379. if(lpReceiveEvent->m_State == EnumWaitFileStartPDU)
  380. {
  381. //Double check to make sure....
  382. lpReceiveEvent->m_bFileCompressed = lpFileStartPDU->GetCompressionFlags() & _MBFT_FILE_COMPRESSED;
  383. if(lpReceiveEvent->m_bFileCompressed)
  384. {
  385. // We don't handle compressed files
  386. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  387. }
  388. BOOL bSuccess = FALSE;
  389. int BytesWritten = 0;
  390. if(lpReceiveEvent->m_bFileCompressed)
  391. {
  392. // We don't handle compressed files
  393. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  394. }
  395. else
  396. {
  397. BytesWritten = lpFileStartPDU->GetDataSize();
  398. if(BytesWritten)
  399. {
  400. if(!lpReceiveEvent->m_lpFile->Write(lpFileStartPDU->GetDataBuffer(),
  401. lpFileStartPDU->GetDataSize()))
  402. {
  403. iErrorCode = (MBFT_ERROR_CODE)lpReceiveEvent->m_lpFile->GetLastErrorCode();
  404. //iMBFT_FILE_IO_ERROR;
  405. }
  406. }
  407. }
  408. //lpReceiveEvent->m_TotalBytesReceived += BytesWritten;
  409. lpReceiveEvent->m_TotalBytesReceived = lpReceiveEvent->m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
  410. lpReceiveEvent->m_FileSize = lpFileStartPDU->GetFileSize();
  411. if(iErrorCode == iMBFT_OK)
  412. {
  413. if(m_State != EnumWaitForTermination)
  414. {
  415. DBG_SAVE_FILE_LINE
  416. m_lpParentEngine->SafePostNotifyMessage(
  417. new FileTransmitMsg(m_EventHandle,
  418. lpReceiveEvent->m_hFile,
  419. lpReceiveEvent->m_FileSize,
  420. lpReceiveEvent->m_TotalBytesReceived,
  421. iMBFT_FILE_RECEIVE_BEGIN,
  422. lpReceiveEvent->m_SenderID,
  423. lpReceiveEvent->m_bIsBroadcast));
  424. }
  425. if(lpFileStartPDU->GetIsEOF())
  426. {
  427. lpReceiveEvent->m_lpFile->SetFileDateTime(lpReceiveEvent->m_FileDateTime);
  428. lpReceiveEvent->m_lpFile->Close();
  429. lpReceiveEvent->m_State = EnumWaitForTermination;
  430. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  431. {
  432. SendFileEndAcknowledgePDU(lpReceiveEvent->m_hFile);
  433. }
  434. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  435. }
  436. else
  437. {
  438. lpReceiveEvent->m_State = EnumWaitFileDataPDU;
  439. }
  440. }
  441. }
  442. } //lpReceiveEvent
  443. } //m_State != EnumWaitForTermination
  444. if(iErrorCode != iMBFT_OK)
  445. {
  446. BOOL bSendChannelLeave = lpReceiveEvent->m_bEOFAcknowledge;
  447. ReportError(lpReceiveEvent,iErrorType,iErrorCode);
  448. ReportReceiverError(lpReceiveEvent,iErrorType,iErrorCode);
  449. lpReceiveEvent->m_lpFile->Close(FALSE);
  450. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  451. if(m_bOKToLeaveDataChannel)
  452. {
  453. if(bSendChannelLeave && m_JoinedToDataChannel)
  454. {
  455. SendChannelLeavePDU();
  456. }
  457. LeaveDataChannel();
  458. }
  459. }
  460. } //wChannelId == m_PrivateMBFTDataChannel
  461. return(bReturn);
  462. }
  463. void MBFTPrivateReceive::ReportError
  464. (
  465. MBFTReceiveSubEvent *lpReceiveEvent,
  466. int iErrorType,
  467. int iErrorCode,
  468. BOOL bIsLocalError,
  469. T120UserID SenderID,
  470. const char* pFileName,
  471. ULONG lFileSize
  472. )
  473. {
  474. if(m_State != EnumWaitForTermination)
  475. {
  476. MBFTMsg * lpNewMessage;
  477. T120UserID id = SenderID ? SenderID : m_LocalMBFTUserID;
  478. DBG_SAVE_FILE_LINE
  479. m_lpParentEngine->SafePostNotifyMessage(
  480. new FileErrorMsg(m_EventHandle,
  481. (lpReceiveEvent) ? lpReceiveEvent->m_hFile : 0, iErrorType,
  482. iErrorCode,
  483. bIsLocalError,
  484. id,
  485. (lpReceiveEvent) ? lpReceiveEvent->m_bIsBroadcast : 0,
  486. pFileName, lFileSize));
  487. }
  488. else
  489. {
  490. TRACERECEIVE(" Waiting for termination, not reporting error");
  491. }
  492. }
  493. void MBFTPrivateReceive::ReportReceiverError
  494. (
  495. MBFTReceiveSubEvent *lpReceive,
  496. int iErrorType,
  497. int iErrorCode,
  498. MBFTFILEHANDLE iFileHandle
  499. )
  500. {
  501. if(m_State != EnumWaitForTermination)
  502. {
  503. if(lpReceive)
  504. {
  505. DBG_SAVE_FILE_LINE
  506. FileErrorPDU * lpNewPDU = new FileErrorPDU(iFileHandle ? iFileHandle : lpReceive->m_hFile,
  507. iErrorType,iErrorCode);
  508. if(lpNewPDU)
  509. {
  510. if(lpNewPDU->Encode())
  511. {
  512. m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  513. APPLET_HIGH_PRIORITY,
  514. (LPBYTE)lpNewPDU->GetBuffer(),
  515. lpNewPDU->GetBufferLength());
  516. }
  517. delete lpNewPDU;
  518. }
  519. }
  520. }
  521. else
  522. {
  523. TRACERECEIVE(" Waiting for termination, not reporting receiver error");
  524. }
  525. }
  526. void MBFTPrivateReceive::DeleteReceiveEvent
  527. (
  528. MBFTReceiveSubEvent *lpReceive,
  529. BOOL bNotifyUser
  530. )
  531. {
  532. if(lpReceive)
  533. {
  534. if(bNotifyUser)
  535. {
  536. DBG_SAVE_FILE_LINE
  537. m_lpParentEngine->SafePostNotifyMessage(
  538. new FileTransmitMsg(m_EventHandle,
  539. lpReceive->m_hFile,
  540. lpReceive->m_FileSize,
  541. lpReceive->m_TotalBytesReceived,
  542. iMBFT_FILE_RECEIVE_END,
  543. lpReceive->m_SenderID,
  544. lpReceive->m_bIsBroadcast));
  545. }
  546. m_ReceiveList.Delete(lpReceive);
  547. if(m_CurrentReceiveEvent == lpReceive)
  548. {
  549. m_CurrentReceiveEvent = NULL;
  550. }
  551. }
  552. }
  553. BOOL MBFTPrivateReceive::OnReceivedFileDataPDU
  554. (
  555. T120ChannelID wChannelId,
  556. T120Priority iPriority,
  557. T120UserID SenderID,
  558. LPFILEDATAPDU lpNewPDU,
  559. BOOL IsUniformSendData
  560. )
  561. {
  562. BOOL bReturn = FALSE;
  563. MBFTReceiveSubEvent * lpReceiveEvent;
  564. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  565. MBFT_ERROR_TYPES iErrorType = MBFT_INFORMATIVE_ERROR;
  566. BOOL bLocalError = TRUE;
  567. if(m_PrivateMBFTDataChannelList.Find(wChannelId))
  568. {
  569. if(m_State != EnumWaitForTermination && m_State != EnumWaitChannelDisband)
  570. {
  571. bReturn = TRUE;
  572. MBFTReceiveSubEvent TempReceive(lpNewPDU->GetFileHandle(),0,NULL,0,SenderID,FALSE,FALSE,FALSE);
  573. lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  574. if(lpReceiveEvent)
  575. {
  576. if(lpReceiveEvent->m_State == EnumWaitFileDataPDU)
  577. {
  578. MBFTMsg * lpNewMessage;
  579. if(!lpNewPDU->GetIsAbort())
  580. {
  581. BOOL bSuccess = FALSE;
  582. int BytesWritten = 0;
  583. if(lpReceiveEvent->m_bFileCompressed)
  584. {
  585. // We don't handle compressed files
  586. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  587. }
  588. else
  589. {
  590. BytesWritten = lpNewPDU->GetDataSize();
  591. if(BytesWritten)
  592. {
  593. if(!lpReceiveEvent->m_lpFile->Write(lpNewPDU->GetDataBuffer(),
  594. lpNewPDU->GetDataSize()))
  595. {
  596. iErrorCode = (MBFT_ERROR_CODE) lpReceiveEvent->m_lpFile->GetLastErrorCode();
  597. //iMBFT_FILE_IO_ERROR;
  598. }
  599. }
  600. }
  601. //lpReceiveEvent->m_TotalBytesReceived += BytesWritten;
  602. lpReceiveEvent->m_TotalBytesReceived = lpReceiveEvent->m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
  603. if(m_State != EnumWaitForTermination)
  604. {
  605. ASSERT(lpReceiveEvent->m_TotalBytesReceived >= lpReceiveEvent->m_cbRecvLastNotify);
  606. ULONG nNotifyDelta = lpReceiveEvent->m_TotalBytesReceived - lpReceiveEvent->m_cbRecvLastNotify;
  607. ULONG nNotifyThreshold = lpReceiveEvent->m_FileSize / 100; // 1%
  608. if (nNotifyDelta >= nNotifyThreshold ||
  609. lpReceiveEvent->m_TotalBytesReceived >= lpReceiveEvent->m_FileSize)
  610. {
  611. DBG_SAVE_FILE_LINE
  612. if (S_OK == m_lpParentEngine->SafePostNotifyMessage(
  613. new FileTransmitMsg(m_EventHandle,
  614. lpReceiveEvent->m_hFile,
  615. lpReceiveEvent->m_FileSize,
  616. lpReceiveEvent->m_TotalBytesReceived,
  617. iMBFT_FILE_RECEIVE_PROGRESS,
  618. lpReceiveEvent->m_SenderID,
  619. lpReceiveEvent->m_bIsBroadcast)))
  620. {
  621. lpReceiveEvent->m_cbRecvLastNotify = lpReceiveEvent->m_TotalBytesReceived;
  622. }
  623. }
  624. }
  625. if(iErrorCode == iMBFT_OK)
  626. {
  627. if(lpNewPDU->GetIsEOF())
  628. {
  629. lpReceiveEvent->m_lpFile->SetFileDateTime(lpReceiveEvent->m_FileDateTime);
  630. lpReceiveEvent->m_lpFile->Close();
  631. lpReceiveEvent->m_State = EnumWaitForTermination;
  632. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  633. {
  634. SendFileEndAcknowledgePDU(lpReceiveEvent->m_hFile);
  635. }
  636. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  637. }
  638. }
  639. }
  640. else
  641. {
  642. ReportError(lpReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  643. FALSE,SenderID);
  644. if(!lpReceiveEvent->m_bFileCompressed)
  645. {
  646. lpReceiveEvent->m_lpFile->Write(lpNewPDU->GetDataBuffer(),
  647. lpNewPDU->GetDataSize());
  648. }
  649. else
  650. {
  651. // We don't handle compressed files
  652. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  653. }
  654. lpReceiveEvent->m_lpFile->Close(FALSE);
  655. lpReceiveEvent->m_State = EnumWaitForTermination;
  656. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  657. }
  658. }
  659. } //lpReceiveEvent
  660. } //m_State != EnumWaitForTermination
  661. if(iErrorCode != iMBFT_OK)
  662. {
  663. T120UserID id = bLocalError ? m_LocalMBFTUserID : SenderID;
  664. ReportError(lpReceiveEvent, iErrorType, iErrorCode, bLocalError, id);
  665. if(bLocalError)
  666. {
  667. ReportReceiverError(lpReceiveEvent,iErrorType,iErrorCode);
  668. }
  669. if(m_bOKToLeaveDataChannel)
  670. {
  671. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  672. {
  673. SendChannelLeavePDU();
  674. }
  675. LeaveDataChannel();
  676. }
  677. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  678. }
  679. } //wChannelId == m_PrivateMBFTDataChannel
  680. return(bReturn);
  681. }
  682. int MBFTPrivateReceive::DecompressAndWrite
  683. (
  684. MBFTReceiveSubEvent *lpReceiveEvent,
  685. LPCSTR lpBuffer,
  686. LONG BufferLength,
  687. LPINT lpDecompressedSize
  688. )
  689. {
  690. return(iMBFT_MEMORY_ALLOCATION_ERROR);
  691. }
  692. BOOL MBFTPrivateReceive::OnReceivedFileErrorPDU
  693. (
  694. T120ChannelID wChannelId,
  695. T120Priority iPriority,
  696. T120UserID SenderID,
  697. LPFILEERRORPDU lpNewPDU,
  698. BOOL IsUniformSendData
  699. )
  700. {
  701. BOOL bReturn = FALSE;
  702. MBFTReceiveSubEvent TempReceive(lpNewPDU->GetFileHandle(),0,NULL,0,SenderID,FALSE,FALSE,FALSE);
  703. MBFTReceiveSubEvent *lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  704. if(lpReceiveEvent)
  705. {
  706. bReturn = TRUE;
  707. ReportError(lpReceiveEvent,lpNewPDU->GetErrorType(),
  708. lpNewPDU->GetErrorCode(),
  709. FALSE,SenderID);
  710. }
  711. else if(m_bProshareTransfer && m_ProshareSenderID == SenderID &&
  712. lpNewPDU->GetFileHandle() == LOWORD(_iMBFT_PROSHARE_ALL_FILES))
  713. {
  714. ReportError(&TempReceive,lpNewPDU->GetErrorType(),
  715. lpNewPDU->GetErrorCode(),
  716. FALSE,SenderID);
  717. bReturn = TRUE;
  718. }
  719. return(bReturn);
  720. }
  721. void MBFTPrivateReceive::DoStateMachine(void)
  722. {
  723. switch(m_State)
  724. {
  725. case EnumWaitSendChannelResponsePDU:
  726. SendChannelResponsePDU();
  727. break;
  728. case EnumWaitSendFileAcceptPDU:
  729. SendFileAcceptPDU();
  730. break;
  731. case EnumWaitSendFileRejectPDU:
  732. SendFileRejectPDU();
  733. break;
  734. case EnumWaitSendFileEndAcknowledgePDU:
  735. SendFileEndAcknowledgePDU();
  736. break;
  737. case EnumWaitSendChannelLeavePDU:
  738. SendChannelLeavePDU();
  739. break;
  740. // caseEnumInitializationFailed:
  741. default:
  742. break;
  743. }
  744. }
  745. BOOL MBFTPrivateReceive::OnMCSChannelAdmitIndication
  746. (
  747. T120ChannelID wChannelId,
  748. T120UserID ManagerID
  749. )
  750. {
  751. BOOL fHandled = FALSE;
  752. //
  753. // More data channels
  754. //
  755. if(m_State == EnumWaitFileOfferPDU)
  756. {
  757. if(m_MBFTDataSenderID == ManagerID)
  758. {
  759. //
  760. // Add the data channel to the list
  761. //
  762. m_PrivateMBFTDataChannelList.Append(wChannelId);
  763. T120ChannelID oldChannel = m_PrivateMBFTDataChannel;
  764. m_PrivateMBFTDataChannel = wChannelId;
  765. JoinDataChannel();
  766. m_PrivateMBFTDataChannel = oldChannel;
  767. fHandled = TRUE;
  768. }
  769. }
  770. else
  771. if(m_State == EnumWaitAdmitControlChannel)
  772. {
  773. if(m_PrivateMBFTControlChannel == wChannelId)
  774. {
  775. m_MBFTControlSenderID = ManagerID;
  776. JoinControlChannel();
  777. fHandled = TRUE;
  778. }
  779. }
  780. else if(m_State == EnumWaitAdmitDataChannelIndication)
  781. {
  782. if (m_PrivateMBFTDataChannelList.Find(wChannelId))
  783. {
  784. m_MBFTDataSenderID = ManagerID;
  785. T120ChannelID oldChannel = m_PrivateMBFTDataChannel;
  786. m_PrivateMBFTDataChannel = wChannelId;
  787. JoinDataChannel();
  788. m_PrivateMBFTDataChannel = oldChannel;
  789. fHandled = TRUE;
  790. }
  791. }
  792. if (! fHandled)
  793. {
  794. UINT chid_uid = MAKELONG(wChannelId, ManagerID);
  795. m_AdmittedChannelQueue.Append(chid_uid);
  796. }
  797. return fHandled;
  798. }
  799. BOOL MBFTPrivateReceive::OnMCSChannelExpelIndication
  800. (
  801. T120ChannelID wChannelId,
  802. Reason iReason
  803. )
  804. {
  805. BOOL bReturn = FALSE;
  806. if(/*(wChannelId == m_PrivateMBFTControlChannel) ||*/
  807. m_PrivateMBFTDataChannelList.Find(wChannelId))
  808. {
  809. TRACERECEIVE(" Channel [%u] disbanded, terminating receive session\n",wChannelId);
  810. //Added by Atul to fix this problem:
  811. //If the sender aborts all files, or the send is aborted when the
  812. //last file is being sent, the sender sends a FileDataPDU with the
  813. ///AbortFlag set to TRUE and proceeds to disband the channel. However,
  814. //on account of a MCS bug, the receiver never sees the PDU (sic).
  815. //Therefore, when we receive a channel expel indication, we check to
  816. //see if we were receiving a file and post a iMBFT_SENDER_ABORTED if necessary...
  817. if(m_CurrentReceiveEvent /* && m_bProshareTransfer */ )
  818. {
  819. if(m_CurrentReceiveEvent->m_State == EnumWaitFileDataPDU ||
  820. m_CurrentReceiveEvent->m_State == EnumWaitFileStartPDU)
  821. {
  822. TRACE(" Unexpected channel disband encountered, posting SENDER_ABORTED message\n");
  823. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  824. FALSE,m_ProshareSenderID);
  825. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  826. m_CurrentReceiveEvent->m_State = EnumWaitForTermination;
  827. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  828. }
  829. }
  830. UnInitialize();
  831. bReturn = TRUE;
  832. }
  833. m_AdmittedChannelQueue.RemoveByChannelID(wChannelId);
  834. return(bReturn);
  835. }
  836. void MBFTPrivateReceive::SendChannelResponsePDU(void)
  837. {
  838. if(m_PrivateMBFTControlChannel >= MIN_ASNDynamicChannelID &&
  839. m_PrivateMBFTControlChannel <= MAX_ASNDynamicChannelID)
  840. {
  841. T127_PRIVATE_CHANNEL_RESPONSE ChannelJoinResponsePDU;
  842. ChannelJoinResponsePDU.pduType = T127_PRIVATE_CHANNEL_JOIN_RESPONSE;
  843. ChannelJoinResponsePDU.ControlChannel = SWAPWORD(m_PrivateMBFTControlChannel - MIN_ASNDynamicChannelID);
  844. ChannelJoinResponsePDU.Response = (ASNPrivate_Channel_Join_ResponsePDU_result_successful << 5);
  845. // if the Mode is FALSE we should use ASNinvitation_rejected
  846. if(m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  847. APPLET_HIGH_PRIORITY,
  848. (LPBYTE)&ChannelJoinResponsePDU,
  849. 4))
  850. {
  851. TRACERECEIVE(" Sent Channel response PDU on [%u]\n",m_MBFTControlSenderID);
  852. m_State = EnumWaitFileOfferPDU;
  853. }
  854. }
  855. else
  856. {
  857. TRACE(" Receive: Fatal Encoding Failure\n");
  858. m_State = EnumInitializationFailed;
  859. //Encoding failed....
  860. }
  861. }
  862. BOOL MBFTPrivateReceive::SendFileAcceptPDU
  863. (
  864. MBFTFILEHANDLE iFileHandle
  865. )
  866. {
  867. m_State = EnumWaitSendFileAcceptPDU;
  868. if(iFileHandle)
  869. {
  870. m_CurrentAcceptHandle = iFileHandle;
  871. }
  872. BOOL bReturn = FALSE;
  873. DBG_SAVE_FILE_LINE
  874. LPFILEACCEPTPDU lpNewPDU = new FileAcceptPDU(m_CurrentAcceptHandle);
  875. if(lpNewPDU)
  876. {
  877. if(lpNewPDU->Encode())
  878. {
  879. if(m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  880. APPLET_HIGH_PRIORITY,
  881. (LPBYTE)lpNewPDU->GetBuffer(),
  882. lpNewPDU->GetBufferLength()))
  883. {
  884. bReturn = TRUE;
  885. TRACERECEIVE(" Sent file accept PDU on [%u]\n",m_MBFTControlSenderID);
  886. m_State = EnumWaitFileOfferPDU;
  887. }
  888. }
  889. else
  890. {
  891. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  892. }
  893. delete lpNewPDU;
  894. }
  895. return(bReturn);
  896. }
  897. void MBFTPrivateReceive::OnControlNotification
  898. (
  899. MBFTFILEHANDLE hFile,
  900. FileTransferControlMsg::FileTransferControl iControlCommand,
  901. LPCSTR lpszDirectory,
  902. LPCSTR lpszFileName
  903. )
  904. {
  905. MBFTReceiveSubEvent * lpReceiveEvent = NULL;
  906. MBFTFILEHANDLE iFileHandle;
  907. BOOL bAbortHack = FALSE;
  908. if(m_State != EnumWaitChannelDisband && m_State != EnumWaitForTermination)
  909. {
  910. MBFTReceiveSubEvent TempReceive(hFile,0,NULL,0,0,FALSE,FALSE,FALSE);
  911. lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  912. if(lpReceiveEvent)
  913. {
  914. iFileHandle = (MBFTFILEHANDLE)lpReceiveEvent->m_hFile;
  915. if(iControlCommand == FileTransferControlMsg::EnumAcceptFile)
  916. {
  917. if(lpReceiveEvent->m_State == EnumWaitUserConfirmation)
  918. {
  919. ::lstrcpynA(lpReceiveEvent->m_szFileDirectory,lpszDirectory,
  920. sizeof(lpReceiveEvent->m_szFileDirectory));
  921. int Length = ::lstrlenA(lpReceiveEvent->m_szFileDirectory);
  922. if(Length >= 3)
  923. {
  924. PCHAR pch = SzFindLastCh(lpReceiveEvent->m_szFileDirectory, '\\');
  925. if ('\0' == *(pch+1))
  926. {
  927. lpReceiveEvent->m_szFileDirectory[Length - 1] = '\0';
  928. }
  929. }
  930. if (::lstrlenA(lpszFileName))
  931. {
  932. ::lstrcpynA(lpReceiveEvent->m_szFileName, lpszFileName, sizeof(lpReceiveEvent->m_szFileName));
  933. }
  934. TRACERECEIVE(" File accept notification for [%u]\n",iFileHandle);
  935. lpReceiveEvent->m_UserAccepted = TRUE;
  936. m_CurrentReceiveEvent = lpReceiveEvent;
  937. if(m_JoinedToDataChannel)
  938. {
  939. SendFileAcceptPDU(iFileHandle);
  940. lpReceiveEvent->m_State = EnumWaitFileStartPDU;
  941. }
  942. else
  943. {
  944. m_State = EnumWaitRejoinDataChannel;
  945. //m_CurrentReceiveEvent = lpReceiveEvent;
  946. JoinDataChannel();
  947. }
  948. }
  949. }
  950. else if(iControlCommand == FileTransferControlMsg::EnumRejectFile)
  951. {
  952. if((lpReceiveEvent->m_State == EnumWaitUserConfirmation) ||
  953. (lpReceiveEvent->m_bIsBroadcast && lpReceiveEvent->m_State == EnumWaitFileStartPDU))
  954. {
  955. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  956. {
  957. iFileHandle = LOWORD(_iMBFT_PROSHARE_ALL_FILES);
  958. }
  959. TRACERECEIVE(" Rejecting file [%u]\n",lpReceiveEvent->m_hFile);
  960. if(m_bOKToLeaveDataChannel)
  961. {
  962. LeaveDataChannel();
  963. }
  964. SendFileRejectPDU(iFileHandle);
  965. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  966. {
  967. TerminateReceiveSession();
  968. }
  969. else
  970. {
  971. DeleteReceiveEvent(lpReceiveEvent,FALSE);
  972. }
  973. }
  974. }
  975. else if(iControlCommand == FileTransferControlMsg::EnumAbortFile)
  976. {
  977. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  978. {
  979. iFileHandle = LOWORD(_iMBFT_PROSHARE_ALL_FILES);
  980. }
  981. if((lpReceiveEvent->m_State == EnumWaitFileDataPDU) ||
  982. (lpReceiveEvent->m_State == EnumWaitFileStartPDU) ||
  983. (hFile == _iMBFT_PROSHARE_ALL_FILES))
  984. {
  985. TRACERECEIVE(" Aborting file [%u]\n",iFileHandle);
  986. if(lpReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation)
  987. {
  988. TRACERECEIVE(" Rejecting file [%u]\n",lpReceiveEvent->m_hFile);
  989. SendFileRejectPDU(iFileHandle);
  990. }
  991. else
  992. {
  993. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  994. {
  995. //If the AbortHack flag is set, we are on a sticky wicket.
  996. //We have already aborted the current file and are waiting
  997. //for another file offer. Therefore we don't inform the sender
  998. //about this one...
  999. if(!bAbortHack)
  1000. {
  1001. ReportReceiverError(lpReceiveEvent,
  1002. MBFT_PERMANENT_ERROR,
  1003. iMBFT_RECEIVER_ABORTED,
  1004. iFileHandle);
  1005. }
  1006. }
  1007. else
  1008. {
  1009. ReportReceiverError(lpReceiveEvent,
  1010. MBFT_PERMANENT_ERROR,
  1011. iMBFT_RECEIVER_ABORTED);
  1012. }
  1013. }
  1014. ReportError(lpReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_RECEIVER_ABORTED);
  1015. if(m_bOKToLeaveDataChannel)
  1016. {
  1017. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  1018. {
  1019. SendChannelLeavePDU();
  1020. }
  1021. LeaveDataChannel();
  1022. }
  1023. if(hFile != _iMBFT_PROSHARE_ALL_FILES)
  1024. {
  1025. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1026. lpReceiveEvent->m_lpFile->Close(FALSE);
  1027. // lpReceiveEvent->m_lpFile->DeleteFile();
  1028. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  1029. }
  1030. else if(m_CurrentReceiveEvent)
  1031. {
  1032. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1033. // m_CurrentReceiveEvent->m_lpFile->DeleteFile();
  1034. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1035. }
  1036. }
  1037. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  1038. {
  1039. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1040. DeleteNotificationMessages(iMBFT_FILE_OFFER);
  1041. TerminateReceiveSession();
  1042. }
  1043. }
  1044. }
  1045. }
  1046. }
  1047. void MBFTPrivateReceive::DeleteNotificationMessages
  1048. (
  1049. MBFT_NOTIFICATION iNotificationType
  1050. )
  1051. {
  1052. #if 0 // lonchanc: no way we can delete notify messages which are already in the queue
  1053. MBFTMsg * lpNewMessage;
  1054. CMsgQueue *pNotifyMsgList = m_lpParentEngine->GetNotificationMsgList();
  1055. CMsgQueue DeleteList;
  1056. pNotifyMsgList->Reset();
  1057. while (NULL != (lpNewMessage = pNotifyMsgList->Iterate()))
  1058. {
  1059. switch (lpNewMessage->GetMsgType())
  1060. {
  1061. case EnumFileTransmitMsg:
  1062. {
  1063. FileTransmitMsg *lpFileMsg = (FileTransmitMsg *)lpNewMessage;
  1064. if(lpFileMsg->m_EventHandle == m_EventHandle)
  1065. {
  1066. if(iNotificationType == lpFileMsg->m_TransmitStatus)
  1067. {
  1068. TRACERECEIVE(" NUKING Notification [%x] from Event [%ld], Handle: [%ld] FileSize: [%ld], Bytes Xfered[%ld]\n",
  1069. lpFileMsg->m_TransmitStatus,lpFileMsg->m_EventHandle,
  1070. lpFileMsg->m_hFile,
  1071. lpFileMsg->m_FileSize,
  1072. lpFileMsg->m_BytesTransmitted);
  1073. DeleteList.Append(lpNewMessage);
  1074. }
  1075. }
  1076. }
  1077. break;
  1078. case EnumFileOfferNotifyMsg:
  1079. {
  1080. FileOfferNotifyMsg *lpFileOfferMsg = (FileOfferNotifyMsg *)lpNewMessage;
  1081. if(lpFileOfferMsg->m_EventHandle == m_EventHandle)
  1082. {
  1083. if(iNotificationType == iMBFT_FILE_OFFER)
  1084. {
  1085. TRACERECEIVE(" NUKING File Offer Notification for [%s], Event: [%ld], Size: [%ld], Handle [%Fp]\n",
  1086. lpFileOfferMsg->m_szFileName,lpFileOfferMsg->m_EventHandle,
  1087. lpFileOfferMsg->m_FileSize,lpFileOfferMsg->m_hFile);
  1088. DeleteList.Append(lpNewMessage);
  1089. }
  1090. }
  1091. }
  1092. break;
  1093. default:
  1094. ASSERT(0);
  1095. break;
  1096. } // switch
  1097. } //for loop
  1098. // remove handled messages
  1099. pNotifyMsgList->DeleteSubset(&DeleteList);
  1100. #endif // 0
  1101. }
  1102. void MBFTPrivateReceive::SendFileRejectPDU
  1103. (
  1104. MBFTFILEHANDLE iFileHandle
  1105. )
  1106. {
  1107. if(m_State != EnumWaitSendFileRejectPDU)
  1108. {
  1109. m_PreviousRejectState = m_State;
  1110. m_State = EnumWaitSendFileRejectPDU;
  1111. }
  1112. if(iFileHandle)
  1113. {
  1114. m_CurrentRejectHandle = iFileHandle;
  1115. }
  1116. FileRejectPDU * lpNewPDU = NULL;
  1117. DBG_SAVE_FILE_LINE
  1118. lpNewPDU = new FileRejectPDU(m_CurrentRejectHandle);
  1119. if(lpNewPDU)
  1120. {
  1121. if(lpNewPDU->Encode())
  1122. {
  1123. if(m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  1124. APPLET_HIGH_PRIORITY,
  1125. (LPBYTE)lpNewPDU->GetBuffer(),
  1126. lpNewPDU->GetBufferLength()))
  1127. {
  1128. m_State = (m_PreviousRejectState != EnumWaitChannelDisband) ?
  1129. EnumWaitFileOfferPDU : EnumWaitChannelDisband;
  1130. }
  1131. }
  1132. else
  1133. {
  1134. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  1135. }
  1136. }
  1137. delete lpNewPDU;
  1138. }
  1139. void MBFTPrivateReceive::SendFileEndAcknowledgePDU
  1140. (
  1141. MBFTFILEHANDLE iFileHandle
  1142. )
  1143. {
  1144. if(iFileHandle)
  1145. {
  1146. m_CurrentFileEndHandle = LOWORD(iFileHandle);
  1147. }
  1148. m_State = EnumWaitSendFileEndAcknowledgePDU;
  1149. DBG_SAVE_FILE_LINE
  1150. FileEndAcknowledgeStruct * lpNewStruct = new FileEndAcknowledgeStruct;
  1151. lpNewStruct->m_FileHandle = m_CurrentFileEndHandle;
  1152. DBG_SAVE_FILE_LINE
  1153. NonStandardPDU * lpNewPDU = new NonStandardPDU(NULL,
  1154. PROSHARE_FILE_END_STRING,
  1155. lpNewStruct,
  1156. sizeof(FileEndAcknowledgeStruct));
  1157. if(lpNewPDU)
  1158. {
  1159. if(lpNewPDU->Encode())
  1160. {
  1161. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTControlChannel,
  1162. APPLET_HIGH_PRIORITY,
  1163. (LPBYTE)lpNewPDU->GetBuffer(),
  1164. lpNewPDU->GetBufferLength()))
  1165. {
  1166. TRACERECEIVE( " Sent FileEndAcknowledgePDU for [%u] on [%u]\n",m_CurrentFileEndHandle,m_PrivateMBFTControlChannel);
  1167. m_State = EnumWaitFileOfferPDU;
  1168. }
  1169. }
  1170. else
  1171. {
  1172. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  1173. }
  1174. delete lpNewPDU;
  1175. }
  1176. delete lpNewStruct;
  1177. }
  1178. void MBFTPrivateReceive::SendChannelLeavePDU(void)
  1179. {
  1180. m_State = EnumWaitSendChannelLeavePDU;
  1181. DBG_SAVE_FILE_LINE
  1182. ChannelLeaveStruct * lpNewStruct = new ChannelLeaveStruct;
  1183. lpNewStruct->m_ChannelID = m_PrivateMBFTDataChannel;
  1184. lpNewStruct->m_ErrorCode = iMBFT_RECEIVER_ABORTED;
  1185. DBG_SAVE_FILE_LINE
  1186. NonStandardPDU * lpNewPDU = new NonStandardPDU(NULL,
  1187. PROSHARE_CHANNEL_LEAVE_STRING,
  1188. lpNewStruct,
  1189. sizeof(ChannelLeaveStruct));
  1190. if(lpNewPDU)
  1191. {
  1192. if(lpNewPDU->Encode())
  1193. {
  1194. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTControlChannel,
  1195. APPLET_HIGH_PRIORITY,
  1196. (LPBYTE)lpNewPDU->GetBuffer(),
  1197. lpNewPDU->GetBufferLength()))
  1198. {
  1199. TRACERECEIVE( " Sent ChannelLeavePDU for [%u] on [%u]\n",m_PrivateMBFTDataChannel,m_PrivateMBFTControlChannel);
  1200. m_State = EnumWaitFileOfferPDU;
  1201. }
  1202. }
  1203. else
  1204. {
  1205. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  1206. }
  1207. delete lpNewPDU;
  1208. }
  1209. delete lpNewStruct;
  1210. }
  1211. void MBFTPrivateReceive::LeaveDataChannel(void)
  1212. {
  1213. if(m_JoinedToDataChannel)
  1214. {
  1215. if(m_lpParentEngine->MCSChannelLeaveRequest(m_PrivateMBFTDataChannel))
  1216. {
  1217. TRACERECEIVE(" Left data channel\n");
  1218. m_JoinedToDataChannel = FALSE;
  1219. }
  1220. }
  1221. }
  1222. void MBFTPrivateReceive::TerminateReceiveSession(void)
  1223. {
  1224. //if(m_lpParentEngine->MCSChannelLeaveRequest(m_PrivateMBFTControlChannel))
  1225. //{
  1226. //TRACERECEIVE(" Left control channel\n");
  1227. //}
  1228. //Keep the clients happy....
  1229. if(!m_bEventEndPosted)
  1230. {
  1231. DBG_SAVE_FILE_LINE
  1232. m_lpParentEngine->SafePostNotifyMessage(new FileEventEndNotifyMsg(m_EventHandle));
  1233. m_bEventEndPosted = TRUE;
  1234. }
  1235. LeaveDataChannel();
  1236. m_State = EnumWaitChannelDisband;
  1237. //UnInitialize();
  1238. }
  1239. void MBFTPrivateReceive::OnPeerDeletedNotification
  1240. (
  1241. CPeerData *lpPeerData
  1242. )
  1243. {
  1244. if(m_bProshareTransfer)
  1245. {
  1246. if(m_ProshareSenderID == lpPeerData->GetUserID())
  1247. {
  1248. if(m_CurrentReceiveEvent)
  1249. {
  1250. if((m_CurrentReceiveEvent->m_State == EnumWaitFileDataPDU) ||
  1251. (m_CurrentReceiveEvent->m_State == EnumWaitFileStartPDU))
  1252. {
  1253. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  1254. FALSE,m_ProshareSenderID);
  1255. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1256. m_CurrentReceiveEvent->m_State = EnumWaitForTermination;
  1257. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1258. }
  1259. }
  1260. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1261. DeleteNotificationMessages(iMBFT_FILE_OFFER);
  1262. TerminateReceiveSession();
  1263. }
  1264. }
  1265. }
  1266. #ifdef USE_BROADCAST_RECEIVE
  1267. MBFTBroadcastReceive::MBFTBroadcastReceive
  1268. (
  1269. LPMBFTENGINE lpParentEngine,
  1270. MBFTEVENTHANDLE EventHandle,
  1271. T120ChannelID wControlChannel,
  1272. T120ChannelID wDataChannel,
  1273. T120UserID SenderID,
  1274. MBFTFILEHANDLE FileHandle
  1275. )
  1276. :
  1277. MBFTPrivateReceive(lpParentEngine, EventHandle, wControlChannel, wDataChannel),
  1278. m_SenderID(SenderID),
  1279. m_FileHandle(FileHandle)
  1280. {
  1281. m_MBFTControlSenderID = m_SenderID;
  1282. m_State = MBFTPrivateReceive::EnumWaitFileOfferPDU;
  1283. }
  1284. BOOL MBFTBroadcastReceive::OnReceivedFileOfferPDU
  1285. (
  1286. T120ChannelID wChannelId,
  1287. T120Priority iPriority,
  1288. T120UserID SenderID,
  1289. T120NodeID NodeID,
  1290. LPFILEOFFERPDU lpNewPDU,
  1291. BOOL IsUniformSendData
  1292. )
  1293. {
  1294. BOOL bReturn = FALSE;
  1295. if(m_State == MBFTPrivateReceive::EnumWaitFileOfferPDU)
  1296. {
  1297. bReturn = (wChannelId == m_PrivateMBFTControlChannel) &&
  1298. (lpNewPDU->GetFileHandle() == m_FileHandle) &&
  1299. (SenderID == m_SenderID);
  1300. if(bReturn)
  1301. {
  1302. MBFTPrivateReceive::OnReceivedFileOfferPDU(wChannelId,
  1303. iPriority,
  1304. SenderID,
  1305. NodeID,
  1306. lpNewPDU,
  1307. IsUniformSendData);
  1308. m_CurrentReceiveEvent = m_ReceiveList.PeekHead();
  1309. if(m_CurrentReceiveEvent)
  1310. {
  1311. ::lstrcpyA(m_CurrentReceiveEvent->m_szFileName,lpNewPDU->GetFileName());
  1312. if(!lpNewPDU->GetAcknowledge())
  1313. {
  1314. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitFileStartPDU;
  1315. }
  1316. else
  1317. {
  1318. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitUserConfirmation;
  1319. }
  1320. }
  1321. else
  1322. {
  1323. UnInitialize();
  1324. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1325. }
  1326. }
  1327. }
  1328. return(bReturn);
  1329. }
  1330. BOOL MBFTBroadcastReceive::OnMCSChannelJoinConfirm
  1331. (
  1332. T120ChannelID wChannelId,
  1333. BOOL bSuccess
  1334. )
  1335. {
  1336. BOOL bReturn = FALSE;
  1337. if(m_State == MBFTPrivateReceive::EnumWaitJoinDataChannel &&
  1338. m_PrivateMBFTDataChannelList.Find(wChannelId))
  1339. {
  1340. bReturn = TRUE;
  1341. m_JoinedToDataChannel = TRUE;
  1342. if(bSuccess && m_CurrentReceiveEvent)
  1343. {
  1344. m_State = MBFTPrivateReceive::EnumWaitSendFileAcceptPDU;
  1345. }
  1346. else
  1347. {
  1348. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1349. LeaveDataChannel();
  1350. UnInitialize();
  1351. }
  1352. }
  1353. return(bReturn);
  1354. }
  1355. BOOL MBFTBroadcastReceive::OnReceivedFileStartPDU
  1356. (
  1357. T120ChannelID wChannelId,
  1358. T120Priority iPriority,
  1359. T120UserID SenderID,
  1360. LPFILESTARTPDU lpFileStartPDU,
  1361. BOOL IsUniformSendData
  1362. )
  1363. {
  1364. BOOL bReturn = FALSE;
  1365. if(m_State == MBFTPrivateReceive::EnumWaitFileStartPDU && m_CurrentReceiveEvent)
  1366. {
  1367. bReturn = m_PrivateMBFTDataChannelList.Find(wChannelId) &&
  1368. (lpFileStartPDU->GetFileHandle() == m_FileHandle) &&
  1369. (SenderID == m_SenderID);
  1370. if(bReturn)
  1371. {
  1372. if(!lstrlen(m_CurrentReceiveEvent->m_szFileName))
  1373. {
  1374. lstrcpy(m_CurrentReceiveEvent->m_szFileName,lpFileStartPDU->GetFileName());
  1375. }
  1376. if(!lstrlen(m_CurrentReceiveEvent->m_szFileDirectory))
  1377. {
  1378. lstrcpy(m_CurrentReceiveEvent->m_szFileDirectory,m_CurrentReceiveEvent->m_lpFile->GetTempDirectory());
  1379. }
  1380. MBFTPrivateReceive::OnReceivedFileStartPDU(wChannelId,
  1381. iPriority,
  1382. SenderID,
  1383. lpFileStartPDU,
  1384. IsUniformSendData);
  1385. //Assumption: m_CurrentReceiveEvent == NULL indicates an error.
  1386. if(!m_CurrentReceiveEvent || lpFileStartPDU->GetIsEOF())
  1387. {
  1388. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1389. UnInitialize();
  1390. }
  1391. else
  1392. {
  1393. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitFileDataPDU;
  1394. }
  1395. }
  1396. }
  1397. return(bReturn);
  1398. }
  1399. BOOL MBFTBroadcastReceive::OnReceivedFileDataPDU
  1400. (
  1401. T120ChannelID wChannelId,
  1402. T120Priority iPriority,
  1403. T120UserID SenderID,
  1404. LPFILEDATAPDU lpNewPDU,
  1405. BOOL IsUniformSendData
  1406. )
  1407. {
  1408. BOOL bReturn = FALSE;
  1409. if(m_State == MBFTPrivateReceive::EnumWaitFileDataPDU && m_CurrentReceiveEvent)
  1410. {
  1411. bReturn = m_PrivateMBFTDataChannelList.Find(wChannelId) &&
  1412. (lpNewPDU->GetFileHandle() == m_FileHandle) &&
  1413. (SenderID == m_SenderID);
  1414. if(bReturn)
  1415. {
  1416. MBFTPrivateReceive::OnReceivedFileDataPDU(wChannelId,
  1417. iPriority,
  1418. SenderID,
  1419. lpNewPDU,
  1420. IsUniformSendData);
  1421. if(!m_CurrentReceiveEvent || lpNewPDU->GetIsEOF())
  1422. {
  1423. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1424. //LeaveDataChannel();
  1425. UnInitialize();
  1426. }
  1427. }
  1428. }
  1429. return(bReturn);
  1430. }
  1431. void MBFTBroadcastReceive::UnInitialize
  1432. (
  1433. BOOL bIsShutDown
  1434. )
  1435. {
  1436. if(m_State != EnumWaitForTermination)
  1437. {
  1438. m_State = EnumWaitForTermination;
  1439. if(!bIsShutDown)
  1440. {
  1441. DBG_SAVE_FILE_LINE
  1442. m_lpParentEngine->SafePostMessage(new DeleteSessionMsg(this));
  1443. if(!m_bEventEndPosted)
  1444. {
  1445. DBG_SAVE_FILE_LINE
  1446. m_lpParentEngine->SafePostNotifyMessage(new FileEventEndNotifyMsg(m_EventHandle));
  1447. m_bEventEndPosted = TRUE;
  1448. }
  1449. }
  1450. }
  1451. }
  1452. void MBFTBroadcastReceive::DoStateMachine(void)
  1453. {
  1454. if(m_State == MBFTPrivateReceive::EnumWaitSendFileAcceptPDU)
  1455. {
  1456. if(m_CurrentReceiveEvent)
  1457. {
  1458. if(SendFileAcceptPDU(m_FileHandle))
  1459. {
  1460. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitFileStartPDU;
  1461. }
  1462. }
  1463. else
  1464. {
  1465. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1466. UnInitialize();
  1467. }
  1468. }
  1469. }
  1470. void MBFTBroadcastReceive::OnControlNotification
  1471. (
  1472. MBFTFILEHANDLE hFile,
  1473. FileTransferControlMsg::FileTransferControl iControlCommand,
  1474. LPCSTR lpszDirectory,
  1475. LPCSTR lpszFileName
  1476. )
  1477. {
  1478. if(m_State != MBFTPrivateReceive::EnumWaitForTermination)
  1479. {
  1480. if(m_CurrentReceiveEvent)
  1481. {
  1482. MBFTFILEHANDLE iFileHandle = (MBFTFILEHANDLE) m_CurrentReceiveEvent->m_hFile;
  1483. if(iControlCommand == FileTransferControlMsg::EnumAcceptFile)
  1484. {
  1485. if(m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation)
  1486. {
  1487. ::lstrcpynA(m_CurrentReceiveEvent->m_szFileDirectory,lpszDirectory,
  1488. sizeof(m_CurrentReceiveEvent->m_szFileDirectory));
  1489. int Length = ::lstrlenA(m_CurrentReceiveEvent->m_szFileDirectory);
  1490. if(Length >= 3)
  1491. {
  1492. PCHAR pch = SzFindLastCh(m_CurrentReceiveEvent->m_szFileDirectory, '\\');
  1493. if ('\0' == *(pch+1))
  1494. {
  1495. m_CurrentReceiveEvent->m_szFileDirectory[Length - 1] = '\0';
  1496. }
  1497. }
  1498. if (::lstrlenA(lpszFileName))
  1499. {
  1500. ::lstrcpynA(m_CurrentReceiveEvent->m_szFileName, lpszFileName, sizeof(m_CurrentReceiveEvent->m_szFileName));
  1501. }
  1502. TRACERECEIVE(" File accept notification for [%u]\n",iFileHandle);
  1503. m_CurrentReceiveEvent->m_UserAccepted = TRUE;
  1504. JoinDataChannel();
  1505. m_State = MBFTPrivateReceive::EnumWaitJoinDataChannel;
  1506. }
  1507. }
  1508. #if 0
  1509. else if(iControlCommand == FileTransferControlMsg::EnumRejectFile)
  1510. {
  1511. if((m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation))
  1512. {
  1513. LeaveDataChannel();
  1514. SendFileRejectPDU(iFileHandle);
  1515. DeleteReceiveEvent(m_CurrentReceiveEvent,FALSE);
  1516. UnInitialize();
  1517. }
  1518. }
  1519. #endif
  1520. else if((iControlCommand == FileTransferControlMsg::EnumAbortFile)
  1521. || (iControlCommand == FileTransferControlMsg::EnumRejectFile))
  1522. {
  1523. if((m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitFileDataPDU) ||
  1524. (m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitFileStartPDU) ||
  1525. (m_CurrentReceiveEvent->m_State == EnumWaitUserConfirmation))
  1526. {
  1527. TRACERECEIVE(" Aborting file [%u]\n",iFileHandle);
  1528. if(m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation)
  1529. {
  1530. //LeaveDataChannel();
  1531. SendFileRejectPDU(iFileHandle);
  1532. //DeleteReceiveEvent(m_CurrentReceiveEvent,FALSE);
  1533. //UnInitialize();
  1534. }
  1535. else
  1536. {
  1537. ReportReceiverError(m_CurrentReceiveEvent,
  1538. MBFT_PERMANENT_ERROR,
  1539. iMBFT_RECEIVER_ABORTED);
  1540. }
  1541. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_RECEIVER_ABORTED);
  1542. LeaveDataChannel();
  1543. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1544. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1545. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1546. UnInitialize();
  1547. }
  1548. }
  1549. }
  1550. }
  1551. }
  1552. void MBFTBroadcastReceive::OnPeerDeletedNotification
  1553. (
  1554. CPeerData *lpPeerData
  1555. )
  1556. {
  1557. if(lpPeerData->GetUserID() == m_SenderID)
  1558. {
  1559. if(m_CurrentReceiveEvent)
  1560. {
  1561. if(m_State == MBFTPrivateReceive::EnumWaitFileStartPDU ||
  1562. m_State == MBFTPrivateReceive::EnumWaitFileDataPDU)
  1563. {
  1564. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  1565. FALSE,m_ProshareSenderID);
  1566. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1567. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1568. }
  1569. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1570. UnInitialize();
  1571. }
  1572. }
  1573. }
  1574. #endif // USE_BROADCAST_RECEIVE
  1575. MBFTReceiveSubEvent * CRecvSubEventList::FindEquiv
  1576. (
  1577. MBFTReceiveSubEvent *pEvent
  1578. )
  1579. {
  1580. MBFTReceiveSubEvent *p;
  1581. Reset();
  1582. while (NULL != (p = Iterate()))
  1583. {
  1584. if (p->IsEqual(pEvent))
  1585. {
  1586. return p;
  1587. }
  1588. }
  1589. return NULL;
  1590. }
  1591. void CRecvSubEventList::Delete
  1592. (
  1593. MBFTReceiveSubEvent *pEvent
  1594. )
  1595. {
  1596. if (Remove(pEvent))
  1597. {
  1598. delete pEvent;
  1599. }
  1600. }
  1601. void CRecvSubEventList::DeleteAll(void)
  1602. {
  1603. MBFTReceiveSubEvent *p;
  1604. while (NULL != (p = Get()))
  1605. {
  1606. delete p;
  1607. }
  1608. }
  1609. BOOL CChannelUidQueue::RemoveByChannelID(T120ChannelID nChannelID)
  1610. {
  1611. UINT_PTR chid_uid;
  1612. Reset();
  1613. while (0 != (chid_uid = Iterate()))
  1614. {
  1615. if (LOWORD(chid_uid) == nChannelID)
  1616. {
  1617. return Remove(chid_uid);
  1618. }
  1619. }
  1620. return FALSE;
  1621. }
  1622. UINT_PTR CChannelUidQueue::FindByChannelID(T120ChannelID nChannelID)
  1623. {
  1624. UINT_PTR chid_uid;
  1625. Reset();
  1626. while (0 != (chid_uid = Iterate()))
  1627. {
  1628. if (LOWORD(chid_uid) == nChannelID)
  1629. {
  1630. return chid_uid;
  1631. }
  1632. }
  1633. return 0;
  1634. }
  1635. LPTSTR GetRootDirPath(LPTSTR pszDirPath, LPTSTR pszRootDirPath, int nSize)
  1636. {
  1637. ::lstrcpy(pszRootDirPath, pszDirPath);
  1638. if (pszRootDirPath[0] == TEXT('\\'))
  1639. {
  1640. if (pszRootDirPath[1] != TEXT('\\'))
  1641. {
  1642. return NULL;
  1643. }
  1644. // the path starts with two '\\'
  1645. BOOL fFirstSlash = FALSE;
  1646. LPTSTR psz = pszRootDirPath + 2;
  1647. while (*psz && !(fFirstSlash && *psz == TEXT('\\')))
  1648. {
  1649. if (*psz == TEXT('\\'))
  1650. {
  1651. fFirstSlash = TRUE;
  1652. }
  1653. psz = ::CharNext(psz);
  1654. }
  1655. *psz++ = '\\';
  1656. *psz = '\0';
  1657. return pszRootDirPath;
  1658. }
  1659. // the first char is not a '\\', it could be driver letter followed by ':'
  1660. if (pszRootDirPath[1] == TEXT(':'))
  1661. {
  1662. pszRootDirPath[2] = TEXT('\\');
  1663. pszRootDirPath[3] = TEXT('\0');
  1664. return pszRootDirPath;
  1665. }
  1666. // the second char is not a ':' , must be a sub directory
  1667. return NULL;
  1668. }
  1669.