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.

1943 lines
63 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. FileTransmitMsg *pFileTransmitMsg;
  416. DBG_SAVE_FILE_LINE
  417. pFileTransmitMsg = new FileTransmitMsg(
  418. m_EventHandle,
  419. lpReceiveEvent->m_hFile,
  420. lpReceiveEvent->m_FileSize,
  421. lpReceiveEvent->m_TotalBytesReceived,
  422. iMBFT_FILE_RECEIVE_BEGIN,
  423. lpReceiveEvent->m_SenderID,
  424. lpReceiveEvent->m_bIsBroadcast);
  425. if(NULL != pFileTransmitMsg)
  426. {
  427. m_lpParentEngine->SafePostNotifyMessage(pFileTransmitMsg);
  428. }
  429. else
  430. {
  431. ERROR_OUT(("Failed to allocate file transmit message"));
  432. }
  433. }
  434. if(lpFileStartPDU->GetIsEOF())
  435. {
  436. lpReceiveEvent->m_lpFile->SetFileDateTime(lpReceiveEvent->m_FileDateTime);
  437. lpReceiveEvent->m_lpFile->Close();
  438. lpReceiveEvent->m_State = EnumWaitForTermination;
  439. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  440. {
  441. SendFileEndAcknowledgePDU(lpReceiveEvent->m_hFile);
  442. }
  443. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  444. }
  445. else
  446. {
  447. lpReceiveEvent->m_State = EnumWaitFileDataPDU;
  448. }
  449. }
  450. }
  451. } //lpReceiveEvent
  452. } //m_State != EnumWaitForTermination
  453. if(iErrorCode != iMBFT_OK)
  454. {
  455. BOOL bSendChannelLeave = lpReceiveEvent->m_bEOFAcknowledge;
  456. ReportError(lpReceiveEvent,iErrorType,iErrorCode);
  457. ReportReceiverError(lpReceiveEvent,iErrorType,iErrorCode);
  458. lpReceiveEvent->m_lpFile->Close(FALSE);
  459. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  460. if(m_bOKToLeaveDataChannel)
  461. {
  462. if(bSendChannelLeave && m_JoinedToDataChannel)
  463. {
  464. SendChannelLeavePDU();
  465. }
  466. LeaveDataChannel();
  467. }
  468. }
  469. } //wChannelId == m_PrivateMBFTDataChannel
  470. return(bReturn);
  471. }
  472. void MBFTPrivateReceive::ReportError
  473. (
  474. MBFTReceiveSubEvent *lpReceiveEvent,
  475. int iErrorType,
  476. int iErrorCode,
  477. BOOL bIsLocalError,
  478. T120UserID SenderID,
  479. const char* pFileName,
  480. ULONG lFileSize
  481. )
  482. {
  483. if(m_State != EnumWaitForTermination)
  484. {
  485. MBFTMsg * lpNewMessage;
  486. T120UserID id = SenderID ? SenderID : m_LocalMBFTUserID;
  487. DBG_SAVE_FILE_LINE
  488. m_lpParentEngine->SafePostNotifyMessage(
  489. new FileErrorMsg(m_EventHandle,
  490. (lpReceiveEvent) ? lpReceiveEvent->m_hFile : 0, iErrorType,
  491. iErrorCode,
  492. bIsLocalError,
  493. id,
  494. (lpReceiveEvent) ? lpReceiveEvent->m_bIsBroadcast : 0,
  495. pFileName, lFileSize));
  496. }
  497. else
  498. {
  499. TRACERECEIVE(" Waiting for termination, not reporting error");
  500. }
  501. }
  502. void MBFTPrivateReceive::ReportReceiverError
  503. (
  504. MBFTReceiveSubEvent *lpReceive,
  505. int iErrorType,
  506. int iErrorCode,
  507. MBFTFILEHANDLE iFileHandle
  508. )
  509. {
  510. if(m_State != EnumWaitForTermination)
  511. {
  512. if(lpReceive)
  513. {
  514. DBG_SAVE_FILE_LINE
  515. FileErrorPDU * lpNewPDU = new FileErrorPDU(iFileHandle ? iFileHandle : lpReceive->m_hFile,
  516. iErrorType,iErrorCode);
  517. if(lpNewPDU)
  518. {
  519. if(lpNewPDU->Encode())
  520. {
  521. m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  522. APPLET_HIGH_PRIORITY,
  523. (LPBYTE)lpNewPDU->GetBuffer(),
  524. lpNewPDU->GetBufferLength());
  525. }
  526. delete lpNewPDU;
  527. }
  528. }
  529. }
  530. else
  531. {
  532. TRACERECEIVE(" Waiting for termination, not reporting receiver error");
  533. }
  534. }
  535. void MBFTPrivateReceive::DeleteReceiveEvent
  536. (
  537. MBFTReceiveSubEvent *lpReceive,
  538. BOOL bNotifyUser
  539. )
  540. {
  541. if(lpReceive)
  542. {
  543. if(bNotifyUser)
  544. {
  545. DBG_SAVE_FILE_LINE
  546. m_lpParentEngine->SafePostNotifyMessage(
  547. new FileTransmitMsg(m_EventHandle,
  548. lpReceive->m_hFile,
  549. lpReceive->m_FileSize,
  550. lpReceive->m_TotalBytesReceived,
  551. iMBFT_FILE_RECEIVE_END,
  552. lpReceive->m_SenderID,
  553. lpReceive->m_bIsBroadcast));
  554. }
  555. m_ReceiveList.Delete(lpReceive);
  556. if(m_CurrentReceiveEvent == lpReceive)
  557. {
  558. m_CurrentReceiveEvent = NULL;
  559. }
  560. }
  561. }
  562. BOOL MBFTPrivateReceive::OnReceivedFileDataPDU
  563. (
  564. T120ChannelID wChannelId,
  565. T120Priority iPriority,
  566. T120UserID SenderID,
  567. LPFILEDATAPDU lpNewPDU,
  568. BOOL IsUniformSendData
  569. )
  570. {
  571. BOOL bReturn = FALSE;
  572. MBFTReceiveSubEvent * lpReceiveEvent;
  573. MBFT_ERROR_CODE iErrorCode = iMBFT_OK;
  574. MBFT_ERROR_TYPES iErrorType = MBFT_INFORMATIVE_ERROR;
  575. BOOL bLocalError = TRUE;
  576. if(m_PrivateMBFTDataChannelList.Find(wChannelId))
  577. {
  578. if(m_State != EnumWaitForTermination && m_State != EnumWaitChannelDisband)
  579. {
  580. bReturn = TRUE;
  581. MBFTReceiveSubEvent TempReceive(lpNewPDU->GetFileHandle(),0,NULL,0,SenderID,FALSE,FALSE,FALSE);
  582. lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  583. if(lpReceiveEvent)
  584. {
  585. if(lpReceiveEvent->m_State == EnumWaitFileDataPDU)
  586. {
  587. MBFTMsg * lpNewMessage;
  588. if(!lpNewPDU->GetIsAbort())
  589. {
  590. BOOL bSuccess = FALSE;
  591. int BytesWritten = 0;
  592. if(lpReceiveEvent->m_bFileCompressed)
  593. {
  594. // We don't handle compressed files
  595. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  596. }
  597. else
  598. {
  599. BytesWritten = lpNewPDU->GetDataSize();
  600. if(BytesWritten)
  601. {
  602. if(!lpReceiveEvent->m_lpFile->Write(lpNewPDU->GetDataBuffer(),
  603. lpNewPDU->GetDataSize()))
  604. {
  605. iErrorCode = (MBFT_ERROR_CODE) lpReceiveEvent->m_lpFile->GetLastErrorCode();
  606. //iMBFT_FILE_IO_ERROR;
  607. }
  608. }
  609. }
  610. //lpReceiveEvent->m_TotalBytesReceived += BytesWritten;
  611. lpReceiveEvent->m_TotalBytesReceived = lpReceiveEvent->m_lpFile->Seek(0L,CMBFTFile::SeekMode::SeekFromCurrent);
  612. if(m_State != EnumWaitForTermination)
  613. {
  614. ASSERT(lpReceiveEvent->m_TotalBytesReceived >= lpReceiveEvent->m_cbRecvLastNotify);
  615. ULONG nNotifyDelta = lpReceiveEvent->m_TotalBytesReceived - lpReceiveEvent->m_cbRecvLastNotify;
  616. ULONG nNotifyThreshold = lpReceiveEvent->m_FileSize / 100; // 1%
  617. if (nNotifyDelta >= nNotifyThreshold ||
  618. lpReceiveEvent->m_TotalBytesReceived >= lpReceiveEvent->m_FileSize)
  619. {
  620. DBG_SAVE_FILE_LINE
  621. if (S_OK == m_lpParentEngine->SafePostNotifyMessage(
  622. new FileTransmitMsg(m_EventHandle,
  623. lpReceiveEvent->m_hFile,
  624. lpReceiveEvent->m_FileSize,
  625. lpReceiveEvent->m_TotalBytesReceived,
  626. iMBFT_FILE_RECEIVE_PROGRESS,
  627. lpReceiveEvent->m_SenderID,
  628. lpReceiveEvent->m_bIsBroadcast)))
  629. {
  630. lpReceiveEvent->m_cbRecvLastNotify = lpReceiveEvent->m_TotalBytesReceived;
  631. }
  632. }
  633. }
  634. if(iErrorCode == iMBFT_OK)
  635. {
  636. if(lpNewPDU->GetIsEOF())
  637. {
  638. lpReceiveEvent->m_lpFile->SetFileDateTime(lpReceiveEvent->m_FileDateTime);
  639. lpReceiveEvent->m_lpFile->Close();
  640. lpReceiveEvent->m_State = EnumWaitForTermination;
  641. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  642. {
  643. SendFileEndAcknowledgePDU(lpReceiveEvent->m_hFile);
  644. }
  645. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  646. }
  647. }
  648. }
  649. else
  650. {
  651. ReportError(lpReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  652. FALSE,SenderID);
  653. if(!lpReceiveEvent->m_bFileCompressed)
  654. {
  655. lpReceiveEvent->m_lpFile->Write(lpNewPDU->GetDataBuffer(),
  656. lpNewPDU->GetDataSize());
  657. }
  658. else
  659. {
  660. // We don't handle compressed files
  661. iErrorCode = iMBFT_MEMORY_ALLOCATION_ERROR;
  662. }
  663. lpReceiveEvent->m_lpFile->Close(FALSE);
  664. lpReceiveEvent->m_State = EnumWaitForTermination;
  665. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  666. }
  667. }
  668. } //lpReceiveEvent
  669. } //m_State != EnumWaitForTermination
  670. if(iErrorCode != iMBFT_OK)
  671. {
  672. T120UserID id = bLocalError ? m_LocalMBFTUserID : SenderID;
  673. ReportError(lpReceiveEvent, iErrorType, iErrorCode, bLocalError, id);
  674. if(bLocalError)
  675. {
  676. ReportReceiverError(lpReceiveEvent,iErrorType,iErrorCode);
  677. }
  678. if(m_bOKToLeaveDataChannel)
  679. {
  680. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  681. {
  682. SendChannelLeavePDU();
  683. }
  684. LeaveDataChannel();
  685. }
  686. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  687. }
  688. } //wChannelId == m_PrivateMBFTDataChannel
  689. return(bReturn);
  690. }
  691. int MBFTPrivateReceive::DecompressAndWrite
  692. (
  693. MBFTReceiveSubEvent *lpReceiveEvent,
  694. LPCSTR lpBuffer,
  695. LONG BufferLength,
  696. LPINT lpDecompressedSize
  697. )
  698. {
  699. return(iMBFT_MEMORY_ALLOCATION_ERROR);
  700. }
  701. BOOL MBFTPrivateReceive::OnReceivedFileErrorPDU
  702. (
  703. T120ChannelID wChannelId,
  704. T120Priority iPriority,
  705. T120UserID SenderID,
  706. LPFILEERRORPDU lpNewPDU,
  707. BOOL IsUniformSendData
  708. )
  709. {
  710. BOOL bReturn = FALSE;
  711. MBFTReceiveSubEvent TempReceive(lpNewPDU->GetFileHandle(),0,NULL,0,SenderID,FALSE,FALSE,FALSE);
  712. MBFTReceiveSubEvent *lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  713. if(lpReceiveEvent)
  714. {
  715. bReturn = TRUE;
  716. ReportError(lpReceiveEvent,lpNewPDU->GetErrorType(),
  717. lpNewPDU->GetErrorCode(),
  718. FALSE,SenderID);
  719. }
  720. else if(m_bProshareTransfer && m_ProshareSenderID == SenderID &&
  721. lpNewPDU->GetFileHandle() == LOWORD(_iMBFT_PROSHARE_ALL_FILES))
  722. {
  723. ReportError(&TempReceive,lpNewPDU->GetErrorType(),
  724. lpNewPDU->GetErrorCode(),
  725. FALSE,SenderID);
  726. bReturn = TRUE;
  727. }
  728. return(bReturn);
  729. }
  730. void MBFTPrivateReceive::DoStateMachine(void)
  731. {
  732. switch(m_State)
  733. {
  734. case EnumWaitSendChannelResponsePDU:
  735. SendChannelResponsePDU();
  736. break;
  737. case EnumWaitSendFileAcceptPDU:
  738. SendFileAcceptPDU();
  739. break;
  740. case EnumWaitSendFileRejectPDU:
  741. SendFileRejectPDU();
  742. break;
  743. case EnumWaitSendFileEndAcknowledgePDU:
  744. SendFileEndAcknowledgePDU();
  745. break;
  746. case EnumWaitSendChannelLeavePDU:
  747. SendChannelLeavePDU();
  748. break;
  749. // caseEnumInitializationFailed:
  750. default:
  751. break;
  752. }
  753. }
  754. BOOL MBFTPrivateReceive::OnMCSChannelAdmitIndication
  755. (
  756. T120ChannelID wChannelId,
  757. T120UserID ManagerID
  758. )
  759. {
  760. BOOL fHandled = FALSE;
  761. //
  762. // More data channels
  763. //
  764. if(m_State == EnumWaitFileOfferPDU)
  765. {
  766. if(m_MBFTDataSenderID == ManagerID)
  767. {
  768. //
  769. // Add the data channel to the list
  770. //
  771. m_PrivateMBFTDataChannelList.Append(wChannelId);
  772. T120ChannelID oldChannel = m_PrivateMBFTDataChannel;
  773. m_PrivateMBFTDataChannel = wChannelId;
  774. JoinDataChannel();
  775. m_PrivateMBFTDataChannel = oldChannel;
  776. fHandled = TRUE;
  777. }
  778. }
  779. else
  780. if(m_State == EnumWaitAdmitControlChannel)
  781. {
  782. if(m_PrivateMBFTControlChannel == wChannelId)
  783. {
  784. m_MBFTControlSenderID = ManagerID;
  785. JoinControlChannel();
  786. fHandled = TRUE;
  787. }
  788. }
  789. else if(m_State == EnumWaitAdmitDataChannelIndication)
  790. {
  791. if (m_PrivateMBFTDataChannelList.Find(wChannelId))
  792. {
  793. m_MBFTDataSenderID = ManagerID;
  794. T120ChannelID oldChannel = m_PrivateMBFTDataChannel;
  795. m_PrivateMBFTDataChannel = wChannelId;
  796. JoinDataChannel();
  797. m_PrivateMBFTDataChannel = oldChannel;
  798. fHandled = TRUE;
  799. }
  800. }
  801. if (! fHandled)
  802. {
  803. UINT chid_uid = MAKELONG(wChannelId, ManagerID);
  804. m_AdmittedChannelQueue.Append(chid_uid);
  805. }
  806. return fHandled;
  807. }
  808. BOOL MBFTPrivateReceive::OnMCSChannelExpelIndication
  809. (
  810. T120ChannelID wChannelId,
  811. Reason iReason
  812. )
  813. {
  814. BOOL bReturn = FALSE;
  815. if(/*(wChannelId == m_PrivateMBFTControlChannel) ||*/
  816. m_PrivateMBFTDataChannelList.Find(wChannelId))
  817. {
  818. TRACERECEIVE(" Channel [%u] disbanded, terminating receive session\n",wChannelId);
  819. //Added by Atul to fix this problem:
  820. //If the sender aborts all files, or the send is aborted when the
  821. //last file is being sent, the sender sends a FileDataPDU with the
  822. ///AbortFlag set to TRUE and proceeds to disband the channel. However,
  823. //on account of a MCS bug, the receiver never sees the PDU (sic).
  824. //Therefore, when we receive a channel expel indication, we check to
  825. //see if we were receiving a file and post a iMBFT_SENDER_ABORTED if necessary...
  826. if(m_CurrentReceiveEvent /* && m_bProshareTransfer */ )
  827. {
  828. if(m_CurrentReceiveEvent->m_State == EnumWaitFileDataPDU ||
  829. m_CurrentReceiveEvent->m_State == EnumWaitFileStartPDU)
  830. {
  831. TRACE(" Unexpected channel disband encountered, posting SENDER_ABORTED message\n");
  832. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  833. FALSE,m_ProshareSenderID);
  834. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  835. m_CurrentReceiveEvent->m_State = EnumWaitForTermination;
  836. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  837. }
  838. }
  839. UnInitialize();
  840. bReturn = TRUE;
  841. }
  842. m_AdmittedChannelQueue.RemoveByChannelID(wChannelId);
  843. return(bReturn);
  844. }
  845. void MBFTPrivateReceive::SendChannelResponsePDU(void)
  846. {
  847. if(m_PrivateMBFTControlChannel >= MIN_ASNDynamicChannelID &&
  848. m_PrivateMBFTControlChannel <= MAX_ASNDynamicChannelID)
  849. {
  850. T127_PRIVATE_CHANNEL_RESPONSE ChannelJoinResponsePDU;
  851. ChannelJoinResponsePDU.pduType = T127_PRIVATE_CHANNEL_JOIN_RESPONSE;
  852. ChannelJoinResponsePDU.ControlChannel = SWAPWORD(m_PrivateMBFTControlChannel - MIN_ASNDynamicChannelID);
  853. ChannelJoinResponsePDU.Response = (ASNPrivate_Channel_Join_ResponsePDU_result_successful << 5);
  854. // if the Mode is FALSE we should use ASNinvitation_rejected
  855. if(m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  856. APPLET_HIGH_PRIORITY,
  857. (LPBYTE)&ChannelJoinResponsePDU,
  858. 4))
  859. {
  860. TRACERECEIVE(" Sent Channel response PDU on [%u]\n",m_MBFTControlSenderID);
  861. m_State = EnumWaitFileOfferPDU;
  862. }
  863. }
  864. else
  865. {
  866. TRACE(" Receive: Fatal Encoding Failure\n");
  867. m_State = EnumInitializationFailed;
  868. //Encoding failed....
  869. }
  870. }
  871. BOOL MBFTPrivateReceive::SendFileAcceptPDU
  872. (
  873. MBFTFILEHANDLE iFileHandle
  874. )
  875. {
  876. m_State = EnumWaitSendFileAcceptPDU;
  877. if(iFileHandle)
  878. {
  879. m_CurrentAcceptHandle = iFileHandle;
  880. }
  881. BOOL bReturn = FALSE;
  882. DBG_SAVE_FILE_LINE
  883. LPFILEACCEPTPDU lpNewPDU = new FileAcceptPDU(m_CurrentAcceptHandle);
  884. if(lpNewPDU)
  885. {
  886. if(lpNewPDU->Encode())
  887. {
  888. if(m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  889. APPLET_HIGH_PRIORITY,
  890. (LPBYTE)lpNewPDU->GetBuffer(),
  891. lpNewPDU->GetBufferLength()))
  892. {
  893. bReturn = TRUE;
  894. TRACERECEIVE(" Sent file accept PDU on [%u]\n",m_MBFTControlSenderID);
  895. m_State = EnumWaitFileOfferPDU;
  896. }
  897. }
  898. else
  899. {
  900. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  901. }
  902. delete lpNewPDU;
  903. }
  904. return(bReturn);
  905. }
  906. void MBFTPrivateReceive::OnControlNotification
  907. (
  908. MBFTFILEHANDLE hFile,
  909. FileTransferControlMsg::FileTransferControl iControlCommand,
  910. LPCSTR lpszDirectory,
  911. LPCSTR lpszFileName
  912. )
  913. {
  914. MBFTReceiveSubEvent * lpReceiveEvent = NULL;
  915. MBFTFILEHANDLE iFileHandle;
  916. BOOL bAbortHack = FALSE;
  917. if(m_State != EnumWaitChannelDisband && m_State != EnumWaitForTermination)
  918. {
  919. MBFTReceiveSubEvent TempReceive(hFile,0,NULL,0,0,FALSE,FALSE,FALSE);
  920. lpReceiveEvent = m_ReceiveList.FindEquiv(&TempReceive);
  921. if(lpReceiveEvent)
  922. {
  923. iFileHandle = (MBFTFILEHANDLE)lpReceiveEvent->m_hFile;
  924. if(iControlCommand == FileTransferControlMsg::EnumAcceptFile)
  925. {
  926. if(lpReceiveEvent->m_State == EnumWaitUserConfirmation)
  927. {
  928. ::lstrcpynA(lpReceiveEvent->m_szFileDirectory,lpszDirectory,
  929. sizeof(lpReceiveEvent->m_szFileDirectory));
  930. int Length = ::lstrlenA(lpReceiveEvent->m_szFileDirectory);
  931. if(Length >= 3)
  932. {
  933. PCHAR pch = SzFindLastCh(lpReceiveEvent->m_szFileDirectory, '\\');
  934. if ('\0' == *(pch+1))
  935. {
  936. lpReceiveEvent->m_szFileDirectory[Length - 1] = '\0';
  937. }
  938. }
  939. if (::lstrlenA(lpszFileName))
  940. {
  941. ::lstrcpynA(lpReceiveEvent->m_szFileName, lpszFileName, sizeof(lpReceiveEvent->m_szFileName));
  942. }
  943. TRACERECEIVE(" File accept notification for [%u]\n",iFileHandle);
  944. lpReceiveEvent->m_UserAccepted = TRUE;
  945. m_CurrentReceiveEvent = lpReceiveEvent;
  946. if(m_JoinedToDataChannel)
  947. {
  948. SendFileAcceptPDU(iFileHandle);
  949. lpReceiveEvent->m_State = EnumWaitFileStartPDU;
  950. }
  951. else
  952. {
  953. m_State = EnumWaitRejoinDataChannel;
  954. //m_CurrentReceiveEvent = lpReceiveEvent;
  955. JoinDataChannel();
  956. }
  957. }
  958. }
  959. else if(iControlCommand == FileTransferControlMsg::EnumRejectFile)
  960. {
  961. if((lpReceiveEvent->m_State == EnumWaitUserConfirmation) ||
  962. (lpReceiveEvent->m_bIsBroadcast && lpReceiveEvent->m_State == EnumWaitFileStartPDU))
  963. {
  964. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  965. {
  966. iFileHandle = LOWORD(_iMBFT_PROSHARE_ALL_FILES);
  967. }
  968. TRACERECEIVE(" Rejecting file [%u]\n",lpReceiveEvent->m_hFile);
  969. if(m_bOKToLeaveDataChannel)
  970. {
  971. LeaveDataChannel();
  972. }
  973. SendFileRejectPDU(iFileHandle);
  974. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  975. {
  976. TerminateReceiveSession();
  977. }
  978. else
  979. {
  980. DeleteReceiveEvent(lpReceiveEvent,FALSE);
  981. }
  982. }
  983. }
  984. else if(iControlCommand == FileTransferControlMsg::EnumAbortFile)
  985. {
  986. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  987. {
  988. iFileHandle = LOWORD(_iMBFT_PROSHARE_ALL_FILES);
  989. }
  990. if((lpReceiveEvent->m_State == EnumWaitFileDataPDU) ||
  991. (lpReceiveEvent->m_State == EnumWaitFileStartPDU) ||
  992. (hFile == _iMBFT_PROSHARE_ALL_FILES))
  993. {
  994. TRACERECEIVE(" Aborting file [%u]\n",iFileHandle);
  995. if(lpReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation)
  996. {
  997. TRACERECEIVE(" Rejecting file [%u]\n",lpReceiveEvent->m_hFile);
  998. SendFileRejectPDU(iFileHandle);
  999. }
  1000. else
  1001. {
  1002. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  1003. {
  1004. //If the AbortHack flag is set, we are on a sticky wicket.
  1005. //We have already aborted the current file and are waiting
  1006. //for another file offer. Therefore we don't inform the sender
  1007. //about this one...
  1008. if(!bAbortHack)
  1009. {
  1010. ReportReceiverError(lpReceiveEvent,
  1011. MBFT_PERMANENT_ERROR,
  1012. iMBFT_RECEIVER_ABORTED,
  1013. iFileHandle);
  1014. }
  1015. }
  1016. else
  1017. {
  1018. ReportReceiverError(lpReceiveEvent,
  1019. MBFT_PERMANENT_ERROR,
  1020. iMBFT_RECEIVER_ABORTED);
  1021. }
  1022. }
  1023. ReportError(lpReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_RECEIVER_ABORTED);
  1024. if(m_bOKToLeaveDataChannel)
  1025. {
  1026. if(lpReceiveEvent->m_bEOFAcknowledge && m_JoinedToDataChannel)
  1027. {
  1028. SendChannelLeavePDU();
  1029. }
  1030. LeaveDataChannel();
  1031. }
  1032. if(hFile != _iMBFT_PROSHARE_ALL_FILES)
  1033. {
  1034. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1035. lpReceiveEvent->m_lpFile->Close(FALSE);
  1036. // lpReceiveEvent->m_lpFile->DeleteFile();
  1037. DeleteReceiveEvent(lpReceiveEvent,TRUE);
  1038. }
  1039. else if(m_CurrentReceiveEvent)
  1040. {
  1041. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1042. // m_CurrentReceiveEvent->m_lpFile->DeleteFile();
  1043. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1044. }
  1045. }
  1046. if(hFile == _iMBFT_PROSHARE_ALL_FILES)
  1047. {
  1048. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1049. DeleteNotificationMessages(iMBFT_FILE_OFFER);
  1050. TerminateReceiveSession();
  1051. }
  1052. }
  1053. }
  1054. }
  1055. }
  1056. void MBFTPrivateReceive::DeleteNotificationMessages
  1057. (
  1058. MBFT_NOTIFICATION iNotificationType
  1059. )
  1060. {
  1061. #if 0 // lonchanc: no way we can delete notify messages which are already in the queue
  1062. MBFTMsg * lpNewMessage;
  1063. CMsgQueue *pNotifyMsgList = m_lpParentEngine->GetNotificationMsgList();
  1064. CMsgQueue DeleteList;
  1065. pNotifyMsgList->Reset();
  1066. while (NULL != (lpNewMessage = pNotifyMsgList->Iterate()))
  1067. {
  1068. switch (lpNewMessage->GetMsgType())
  1069. {
  1070. case EnumFileTransmitMsg:
  1071. {
  1072. FileTransmitMsg *lpFileMsg = (FileTransmitMsg *)lpNewMessage;
  1073. if(lpFileMsg->m_EventHandle == m_EventHandle)
  1074. {
  1075. if(iNotificationType == lpFileMsg->m_TransmitStatus)
  1076. {
  1077. TRACERECEIVE(" NUKING Notification [%x] from Event [%ld], Handle: [%ld] FileSize: [%ld], Bytes Xfered[%ld]\n",
  1078. lpFileMsg->m_TransmitStatus,lpFileMsg->m_EventHandle,
  1079. lpFileMsg->m_hFile,
  1080. lpFileMsg->m_FileSize,
  1081. lpFileMsg->m_BytesTransmitted);
  1082. DeleteList.Append(lpNewMessage);
  1083. }
  1084. }
  1085. }
  1086. break;
  1087. case EnumFileOfferNotifyMsg:
  1088. {
  1089. FileOfferNotifyMsg *lpFileOfferMsg = (FileOfferNotifyMsg *)lpNewMessage;
  1090. if(lpFileOfferMsg->m_EventHandle == m_EventHandle)
  1091. {
  1092. if(iNotificationType == iMBFT_FILE_OFFER)
  1093. {
  1094. TRACERECEIVE(" NUKING File Offer Notification for [%s], Event: [%ld], Size: [%ld], Handle [%Fp]\n",
  1095. lpFileOfferMsg->m_szFileName,lpFileOfferMsg->m_EventHandle,
  1096. lpFileOfferMsg->m_FileSize,lpFileOfferMsg->m_hFile);
  1097. DeleteList.Append(lpNewMessage);
  1098. }
  1099. }
  1100. }
  1101. break;
  1102. default:
  1103. ASSERT(0);
  1104. break;
  1105. } // switch
  1106. } //for loop
  1107. // remove handled messages
  1108. pNotifyMsgList->DeleteSubset(&DeleteList);
  1109. #endif // 0
  1110. }
  1111. void MBFTPrivateReceive::SendFileRejectPDU
  1112. (
  1113. MBFTFILEHANDLE iFileHandle
  1114. )
  1115. {
  1116. if(m_State != EnumWaitSendFileRejectPDU)
  1117. {
  1118. m_PreviousRejectState = m_State;
  1119. m_State = EnumWaitSendFileRejectPDU;
  1120. }
  1121. if(iFileHandle)
  1122. {
  1123. m_CurrentRejectHandle = iFileHandle;
  1124. }
  1125. FileRejectPDU * lpNewPDU = NULL;
  1126. DBG_SAVE_FILE_LINE
  1127. lpNewPDU = new FileRejectPDU(m_CurrentRejectHandle);
  1128. if(lpNewPDU)
  1129. {
  1130. if(lpNewPDU->Encode())
  1131. {
  1132. if(m_lpParentEngine->SendDataRequest(m_MBFTControlSenderID,
  1133. APPLET_HIGH_PRIORITY,
  1134. (LPBYTE)lpNewPDU->GetBuffer(),
  1135. lpNewPDU->GetBufferLength()))
  1136. {
  1137. m_State = (m_PreviousRejectState != EnumWaitChannelDisband) ?
  1138. EnumWaitFileOfferPDU : EnumWaitChannelDisband;
  1139. }
  1140. }
  1141. else
  1142. {
  1143. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  1144. }
  1145. }
  1146. delete lpNewPDU;
  1147. }
  1148. void MBFTPrivateReceive::SendFileEndAcknowledgePDU
  1149. (
  1150. MBFTFILEHANDLE iFileHandle
  1151. )
  1152. {
  1153. if(iFileHandle)
  1154. {
  1155. m_CurrentFileEndHandle = LOWORD(iFileHandle);
  1156. }
  1157. m_State = EnumWaitSendFileEndAcknowledgePDU;
  1158. DBG_SAVE_FILE_LINE
  1159. FileEndAcknowledgeStruct * lpNewStruct = new FileEndAcknowledgeStruct;
  1160. lpNewStruct->m_FileHandle = m_CurrentFileEndHandle;
  1161. DBG_SAVE_FILE_LINE
  1162. NonStandardPDU * lpNewPDU = new NonStandardPDU(NULL,
  1163. PROSHARE_FILE_END_STRING,
  1164. lpNewStruct,
  1165. sizeof(FileEndAcknowledgeStruct));
  1166. if(lpNewPDU)
  1167. {
  1168. if(lpNewPDU->Encode())
  1169. {
  1170. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTControlChannel,
  1171. APPLET_HIGH_PRIORITY,
  1172. (LPBYTE)lpNewPDU->GetBuffer(),
  1173. lpNewPDU->GetBufferLength()))
  1174. {
  1175. TRACERECEIVE( " Sent FileEndAcknowledgePDU for [%u] on [%u]\n",m_CurrentFileEndHandle,m_PrivateMBFTControlChannel);
  1176. m_State = EnumWaitFileOfferPDU;
  1177. }
  1178. }
  1179. else
  1180. {
  1181. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  1182. }
  1183. delete lpNewPDU;
  1184. }
  1185. delete lpNewStruct;
  1186. }
  1187. void MBFTPrivateReceive::SendChannelLeavePDU(void)
  1188. {
  1189. m_State = EnumWaitSendChannelLeavePDU;
  1190. DBG_SAVE_FILE_LINE
  1191. ChannelLeaveStruct * lpNewStruct = new ChannelLeaveStruct;
  1192. lpNewStruct->m_ChannelID = m_PrivateMBFTDataChannel;
  1193. lpNewStruct->m_ErrorCode = iMBFT_RECEIVER_ABORTED;
  1194. DBG_SAVE_FILE_LINE
  1195. NonStandardPDU * lpNewPDU = new NonStandardPDU(NULL,
  1196. PROSHARE_CHANNEL_LEAVE_STRING,
  1197. lpNewStruct,
  1198. sizeof(ChannelLeaveStruct));
  1199. if(lpNewPDU)
  1200. {
  1201. if(lpNewPDU->Encode())
  1202. {
  1203. if(m_lpParentEngine->SendDataRequest(m_PrivateMBFTControlChannel,
  1204. APPLET_HIGH_PRIORITY,
  1205. (LPBYTE)lpNewPDU->GetBuffer(),
  1206. lpNewPDU->GetBufferLength()))
  1207. {
  1208. TRACERECEIVE( " Sent ChannelLeavePDU for [%u] on [%u]\n",m_PrivateMBFTDataChannel,m_PrivateMBFTControlChannel);
  1209. m_State = EnumWaitFileOfferPDU;
  1210. }
  1211. }
  1212. else
  1213. {
  1214. ReportError(m_CurrentReceiveEvent,MBFT_PERMANENT_ERROR,iMBFT_ASN1_ENCODING_ERROR);
  1215. }
  1216. delete lpNewPDU;
  1217. }
  1218. delete lpNewStruct;
  1219. }
  1220. void MBFTPrivateReceive::LeaveDataChannel(void)
  1221. {
  1222. if(m_JoinedToDataChannel)
  1223. {
  1224. if(m_lpParentEngine->MCSChannelLeaveRequest(m_PrivateMBFTDataChannel))
  1225. {
  1226. TRACERECEIVE(" Left data channel\n");
  1227. m_JoinedToDataChannel = FALSE;
  1228. }
  1229. }
  1230. }
  1231. void MBFTPrivateReceive::TerminateReceiveSession(void)
  1232. {
  1233. //if(m_lpParentEngine->MCSChannelLeaveRequest(m_PrivateMBFTControlChannel))
  1234. //{
  1235. //TRACERECEIVE(" Left control channel\n");
  1236. //}
  1237. //Keep the clients happy....
  1238. if(!m_bEventEndPosted)
  1239. {
  1240. DBG_SAVE_FILE_LINE
  1241. m_lpParentEngine->SafePostNotifyMessage(new FileEventEndNotifyMsg(m_EventHandle));
  1242. m_bEventEndPosted = TRUE;
  1243. }
  1244. LeaveDataChannel();
  1245. m_State = EnumWaitChannelDisband;
  1246. //UnInitialize();
  1247. }
  1248. void MBFTPrivateReceive::OnPeerDeletedNotification
  1249. (
  1250. CPeerData *lpPeerData
  1251. )
  1252. {
  1253. if(m_bProshareTransfer)
  1254. {
  1255. if(m_ProshareSenderID == lpPeerData->GetUserID())
  1256. {
  1257. if(m_CurrentReceiveEvent)
  1258. {
  1259. if((m_CurrentReceiveEvent->m_State == EnumWaitFileDataPDU) ||
  1260. (m_CurrentReceiveEvent->m_State == EnumWaitFileStartPDU))
  1261. {
  1262. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  1263. FALSE,m_ProshareSenderID);
  1264. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1265. m_CurrentReceiveEvent->m_State = EnumWaitForTermination;
  1266. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1267. }
  1268. }
  1269. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1270. DeleteNotificationMessages(iMBFT_FILE_OFFER);
  1271. TerminateReceiveSession();
  1272. }
  1273. }
  1274. }
  1275. #ifdef USE_BROADCAST_RECEIVE
  1276. MBFTBroadcastReceive::MBFTBroadcastReceive
  1277. (
  1278. LPMBFTENGINE lpParentEngine,
  1279. MBFTEVENTHANDLE EventHandle,
  1280. T120ChannelID wControlChannel,
  1281. T120ChannelID wDataChannel,
  1282. T120UserID SenderID,
  1283. MBFTFILEHANDLE FileHandle
  1284. )
  1285. :
  1286. MBFTPrivateReceive(lpParentEngine, EventHandle, wControlChannel, wDataChannel),
  1287. m_SenderID(SenderID),
  1288. m_FileHandle(FileHandle)
  1289. {
  1290. m_MBFTControlSenderID = m_SenderID;
  1291. m_State = MBFTPrivateReceive::EnumWaitFileOfferPDU;
  1292. }
  1293. BOOL MBFTBroadcastReceive::OnReceivedFileOfferPDU
  1294. (
  1295. T120ChannelID wChannelId,
  1296. T120Priority iPriority,
  1297. T120UserID SenderID,
  1298. T120NodeID NodeID,
  1299. LPFILEOFFERPDU lpNewPDU,
  1300. BOOL IsUniformSendData
  1301. )
  1302. {
  1303. BOOL bReturn = FALSE;
  1304. if(m_State == MBFTPrivateReceive::EnumWaitFileOfferPDU)
  1305. {
  1306. bReturn = (wChannelId == m_PrivateMBFTControlChannel) &&
  1307. (lpNewPDU->GetFileHandle() == m_FileHandle) &&
  1308. (SenderID == m_SenderID);
  1309. if(bReturn)
  1310. {
  1311. MBFTPrivateReceive::OnReceivedFileOfferPDU(wChannelId,
  1312. iPriority,
  1313. SenderID,
  1314. NodeID,
  1315. lpNewPDU,
  1316. IsUniformSendData);
  1317. m_CurrentReceiveEvent = m_ReceiveList.PeekHead();
  1318. if(m_CurrentReceiveEvent)
  1319. {
  1320. ::lstrcpyA(m_CurrentReceiveEvent->m_szFileName,lpNewPDU->GetFileName());
  1321. if(!lpNewPDU->GetAcknowledge())
  1322. {
  1323. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitFileStartPDU;
  1324. }
  1325. else
  1326. {
  1327. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitUserConfirmation;
  1328. }
  1329. }
  1330. else
  1331. {
  1332. UnInitialize();
  1333. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1334. }
  1335. }
  1336. }
  1337. return(bReturn);
  1338. }
  1339. BOOL MBFTBroadcastReceive::OnMCSChannelJoinConfirm
  1340. (
  1341. T120ChannelID wChannelId,
  1342. BOOL bSuccess
  1343. )
  1344. {
  1345. BOOL bReturn = FALSE;
  1346. if(m_State == MBFTPrivateReceive::EnumWaitJoinDataChannel &&
  1347. m_PrivateMBFTDataChannelList.Find(wChannelId))
  1348. {
  1349. bReturn = TRUE;
  1350. m_JoinedToDataChannel = TRUE;
  1351. if(bSuccess && m_CurrentReceiveEvent)
  1352. {
  1353. m_State = MBFTPrivateReceive::EnumWaitSendFileAcceptPDU;
  1354. }
  1355. else
  1356. {
  1357. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1358. LeaveDataChannel();
  1359. UnInitialize();
  1360. }
  1361. }
  1362. return(bReturn);
  1363. }
  1364. BOOL MBFTBroadcastReceive::OnReceivedFileStartPDU
  1365. (
  1366. T120ChannelID wChannelId,
  1367. T120Priority iPriority,
  1368. T120UserID SenderID,
  1369. LPFILESTARTPDU lpFileStartPDU,
  1370. BOOL IsUniformSendData
  1371. )
  1372. {
  1373. BOOL bReturn = FALSE;
  1374. if(m_State == MBFTPrivateReceive::EnumWaitFileStartPDU && m_CurrentReceiveEvent)
  1375. {
  1376. bReturn = m_PrivateMBFTDataChannelList.Find(wChannelId) &&
  1377. (lpFileStartPDU->GetFileHandle() == m_FileHandle) &&
  1378. (SenderID == m_SenderID);
  1379. if(bReturn)
  1380. {
  1381. if(!lstrlen(m_CurrentReceiveEvent->m_szFileName))
  1382. {
  1383. lstrcpy(m_CurrentReceiveEvent->m_szFileName,lpFileStartPDU->GetFileName());
  1384. }
  1385. if(!lstrlen(m_CurrentReceiveEvent->m_szFileDirectory))
  1386. {
  1387. lstrcpy(m_CurrentReceiveEvent->m_szFileDirectory,m_CurrentReceiveEvent->m_lpFile->GetTempDirectory());
  1388. }
  1389. MBFTPrivateReceive::OnReceivedFileStartPDU(wChannelId,
  1390. iPriority,
  1391. SenderID,
  1392. lpFileStartPDU,
  1393. IsUniformSendData);
  1394. //Assumption: m_CurrentReceiveEvent == NULL indicates an error.
  1395. if(!m_CurrentReceiveEvent || lpFileStartPDU->GetIsEOF())
  1396. {
  1397. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1398. UnInitialize();
  1399. }
  1400. else
  1401. {
  1402. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitFileDataPDU;
  1403. }
  1404. }
  1405. }
  1406. return(bReturn);
  1407. }
  1408. BOOL MBFTBroadcastReceive::OnReceivedFileDataPDU
  1409. (
  1410. T120ChannelID wChannelId,
  1411. T120Priority iPriority,
  1412. T120UserID SenderID,
  1413. LPFILEDATAPDU lpNewPDU,
  1414. BOOL IsUniformSendData
  1415. )
  1416. {
  1417. BOOL bReturn = FALSE;
  1418. if(m_State == MBFTPrivateReceive::EnumWaitFileDataPDU && m_CurrentReceiveEvent)
  1419. {
  1420. bReturn = m_PrivateMBFTDataChannelList.Find(wChannelId) &&
  1421. (lpNewPDU->GetFileHandle() == m_FileHandle) &&
  1422. (SenderID == m_SenderID);
  1423. if(bReturn)
  1424. {
  1425. MBFTPrivateReceive::OnReceivedFileDataPDU(wChannelId,
  1426. iPriority,
  1427. SenderID,
  1428. lpNewPDU,
  1429. IsUniformSendData);
  1430. if(!m_CurrentReceiveEvent || lpNewPDU->GetIsEOF())
  1431. {
  1432. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1433. //LeaveDataChannel();
  1434. UnInitialize();
  1435. }
  1436. }
  1437. }
  1438. return(bReturn);
  1439. }
  1440. void MBFTBroadcastReceive::UnInitialize
  1441. (
  1442. BOOL bIsShutDown
  1443. )
  1444. {
  1445. if(m_State != EnumWaitForTermination)
  1446. {
  1447. m_State = EnumWaitForTermination;
  1448. if(!bIsShutDown)
  1449. {
  1450. DBG_SAVE_FILE_LINE
  1451. m_lpParentEngine->SafePostMessage(new DeleteSessionMsg(this));
  1452. if(!m_bEventEndPosted)
  1453. {
  1454. DBG_SAVE_FILE_LINE
  1455. m_lpParentEngine->SafePostNotifyMessage(new FileEventEndNotifyMsg(m_EventHandle));
  1456. m_bEventEndPosted = TRUE;
  1457. }
  1458. }
  1459. }
  1460. }
  1461. void MBFTBroadcastReceive::DoStateMachine(void)
  1462. {
  1463. if(m_State == MBFTPrivateReceive::EnumWaitSendFileAcceptPDU)
  1464. {
  1465. if(m_CurrentReceiveEvent)
  1466. {
  1467. if(SendFileAcceptPDU(m_FileHandle))
  1468. {
  1469. m_State = m_CurrentReceiveEvent->m_State = MBFTPrivateReceive::EnumWaitFileStartPDU;
  1470. }
  1471. }
  1472. else
  1473. {
  1474. //m_State = MBFTPrivateReceive::EnumWaitForTermination;
  1475. UnInitialize();
  1476. }
  1477. }
  1478. }
  1479. void MBFTBroadcastReceive::OnControlNotification
  1480. (
  1481. MBFTFILEHANDLE hFile,
  1482. FileTransferControlMsg::FileTransferControl iControlCommand,
  1483. LPCSTR lpszDirectory,
  1484. LPCSTR lpszFileName
  1485. )
  1486. {
  1487. if(m_State != MBFTPrivateReceive::EnumWaitForTermination)
  1488. {
  1489. if(m_CurrentReceiveEvent)
  1490. {
  1491. MBFTFILEHANDLE iFileHandle = (MBFTFILEHANDLE) m_CurrentReceiveEvent->m_hFile;
  1492. if(iControlCommand == FileTransferControlMsg::EnumAcceptFile)
  1493. {
  1494. if(m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation)
  1495. {
  1496. ::lstrcpynA(m_CurrentReceiveEvent->m_szFileDirectory,lpszDirectory,
  1497. sizeof(m_CurrentReceiveEvent->m_szFileDirectory));
  1498. int Length = ::lstrlenA(m_CurrentReceiveEvent->m_szFileDirectory);
  1499. if(Length >= 3)
  1500. {
  1501. PCHAR pch = SzFindLastCh(m_CurrentReceiveEvent->m_szFileDirectory, '\\');
  1502. if ('\0' == *(pch+1))
  1503. {
  1504. m_CurrentReceiveEvent->m_szFileDirectory[Length - 1] = '\0';
  1505. }
  1506. }
  1507. if (::lstrlenA(lpszFileName))
  1508. {
  1509. ::lstrcpynA(m_CurrentReceiveEvent->m_szFileName, lpszFileName, sizeof(m_CurrentReceiveEvent->m_szFileName));
  1510. }
  1511. TRACERECEIVE(" File accept notification for [%u]\n",iFileHandle);
  1512. m_CurrentReceiveEvent->m_UserAccepted = TRUE;
  1513. JoinDataChannel();
  1514. m_State = MBFTPrivateReceive::EnumWaitJoinDataChannel;
  1515. }
  1516. }
  1517. #if 0
  1518. else if(iControlCommand == FileTransferControlMsg::EnumRejectFile)
  1519. {
  1520. if((m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation))
  1521. {
  1522. LeaveDataChannel();
  1523. SendFileRejectPDU(iFileHandle);
  1524. DeleteReceiveEvent(m_CurrentReceiveEvent,FALSE);
  1525. UnInitialize();
  1526. }
  1527. }
  1528. #endif
  1529. else if((iControlCommand == FileTransferControlMsg::EnumAbortFile)
  1530. || (iControlCommand == FileTransferControlMsg::EnumRejectFile))
  1531. {
  1532. if((m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitFileDataPDU) ||
  1533. (m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitFileStartPDU) ||
  1534. (m_CurrentReceiveEvent->m_State == EnumWaitUserConfirmation))
  1535. {
  1536. TRACERECEIVE(" Aborting file [%u]\n",iFileHandle);
  1537. if(m_CurrentReceiveEvent->m_State == MBFTPrivateReceive::EnumWaitUserConfirmation)
  1538. {
  1539. //LeaveDataChannel();
  1540. SendFileRejectPDU(iFileHandle);
  1541. //DeleteReceiveEvent(m_CurrentReceiveEvent,FALSE);
  1542. //UnInitialize();
  1543. }
  1544. else
  1545. {
  1546. ReportReceiverError(m_CurrentReceiveEvent,
  1547. MBFT_PERMANENT_ERROR,
  1548. iMBFT_RECEIVER_ABORTED);
  1549. }
  1550. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_RECEIVER_ABORTED);
  1551. LeaveDataChannel();
  1552. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1553. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1554. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1555. UnInitialize();
  1556. }
  1557. }
  1558. }
  1559. }
  1560. }
  1561. void MBFTBroadcastReceive::OnPeerDeletedNotification
  1562. (
  1563. CPeerData *lpPeerData
  1564. )
  1565. {
  1566. if(lpPeerData->GetUserID() == m_SenderID)
  1567. {
  1568. if(m_CurrentReceiveEvent)
  1569. {
  1570. if(m_State == MBFTPrivateReceive::EnumWaitFileStartPDU ||
  1571. m_State == MBFTPrivateReceive::EnumWaitFileDataPDU)
  1572. {
  1573. ReportError(m_CurrentReceiveEvent,MBFT_INFORMATIVE_ERROR,iMBFT_SENDER_ABORTED,
  1574. FALSE,m_ProshareSenderID);
  1575. m_CurrentReceiveEvent->m_lpFile->Close(FALSE);
  1576. DeleteReceiveEvent(m_CurrentReceiveEvent,TRUE);
  1577. }
  1578. DeleteNotificationMessages(iMBFT_FILE_RECEIVE_PROGRESS);
  1579. UnInitialize();
  1580. }
  1581. }
  1582. }
  1583. #endif // USE_BROADCAST_RECEIVE
  1584. MBFTReceiveSubEvent * CRecvSubEventList::FindEquiv
  1585. (
  1586. MBFTReceiveSubEvent *pEvent
  1587. )
  1588. {
  1589. MBFTReceiveSubEvent *p;
  1590. Reset();
  1591. while (NULL != (p = Iterate()))
  1592. {
  1593. if (p->IsEqual(pEvent))
  1594. {
  1595. return p;
  1596. }
  1597. }
  1598. return NULL;
  1599. }
  1600. void CRecvSubEventList::Delete
  1601. (
  1602. MBFTReceiveSubEvent *pEvent
  1603. )
  1604. {
  1605. if (Remove(pEvent))
  1606. {
  1607. delete pEvent;
  1608. }
  1609. }
  1610. void CRecvSubEventList::DeleteAll(void)
  1611. {
  1612. MBFTReceiveSubEvent *p;
  1613. while (NULL != (p = Get()))
  1614. {
  1615. delete p;
  1616. }
  1617. }
  1618. BOOL CChannelUidQueue::RemoveByChannelID(T120ChannelID nChannelID)
  1619. {
  1620. UINT_PTR chid_uid;
  1621. Reset();
  1622. while (0 != (chid_uid = Iterate()))
  1623. {
  1624. if (LOWORD(chid_uid) == nChannelID)
  1625. {
  1626. return Remove(chid_uid);
  1627. }
  1628. }
  1629. return FALSE;
  1630. }
  1631. UINT_PTR CChannelUidQueue::FindByChannelID(T120ChannelID nChannelID)
  1632. {
  1633. UINT_PTR chid_uid;
  1634. Reset();
  1635. while (0 != (chid_uid = Iterate()))
  1636. {
  1637. if (LOWORD(chid_uid) == nChannelID)
  1638. {
  1639. return chid_uid;
  1640. }
  1641. }
  1642. return 0;
  1643. }
  1644. LPTSTR GetRootDirPath(LPTSTR pszDirPath, LPTSTR pszRootDirPath, int nSize)
  1645. {
  1646. ::lstrcpy(pszRootDirPath, pszDirPath);
  1647. if (pszRootDirPath[0] == TEXT('\\'))
  1648. {
  1649. if (pszRootDirPath[1] != TEXT('\\'))
  1650. {
  1651. return NULL;
  1652. }
  1653. // the path starts with two '\\'
  1654. BOOL fFirstSlash = FALSE;
  1655. LPTSTR psz = pszRootDirPath + 2;
  1656. while (*psz && !(fFirstSlash && *psz == TEXT('\\')))
  1657. {
  1658. if (*psz == TEXT('\\'))
  1659. {
  1660. fFirstSlash = TRUE;
  1661. }
  1662. psz = ::CharNext(psz);
  1663. }
  1664. *psz++ = '\\';
  1665. *psz = '\0';
  1666. return pszRootDirPath;
  1667. }
  1668. // the first char is not a '\\', it could be driver letter followed by ':'
  1669. if (pszRootDirPath[1] == TEXT(':'))
  1670. {
  1671. pszRootDirPath[2] = TEXT('\\');
  1672. pszRootDirPath[3] = TEXT('\0');
  1673. return pszRootDirPath;
  1674. }
  1675. // the second char is not a ':' , must be a sub directory
  1676. return NULL;
  1677. }
  1678.