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.

2030 lines
68 KiB

  1. /* file: mbft.cpp */
  2. #include "mbftpch.h"
  3. #include <it120app.h>
  4. #include <version.h>
  5. #define __NO_EXTERNS__
  6. #include "mbft.hpp"
  7. #include "osshelp.hpp"
  8. #include "messages.hpp"
  9. #include "mbftrecv.hpp"
  10. #include "mbftsend.hpp"
  11. void CALLBACK T120Callback(T120AppletSessionMsg *);
  12. // from mbftapi.cpp
  13. BOOL g_fWaitingForBufferAvailable = FALSE;
  14. #ifdef ENABLE_HEARTBEAT_TIMER
  15. // WM_TIMER has the lowest priority among window messages
  16. #define IDLE_TIMER_SPEED 5000
  17. #define SESSION_TIMER_SPEED 20
  18. void HeartBeatTimerProc(HWND hWnd, UINT uMsg, UINT_PTR nTimerID, DWORD dwTime)
  19. {
  20. if (NULL != g_pFileXferApplet)
  21. {
  22. MBFTEngine *pEngine = g_pFileXferApplet->FindEngineByTimerID(nTimerID);
  23. if (NULL != pEngine)
  24. {
  25. ::PostMessage(g_pFileXferApplet->GetHiddenWnd(), MBFTMSG_HEART_BEAT,
  26. 0, (LPARAM) pEngine);
  27. }
  28. }
  29. }
  30. #endif
  31. MBFTEngine::MBFTEngine
  32. (
  33. MBFTInterface *pMBFTIntf,
  34. MBFT_MODE eMode,
  35. T120SessionID nSessionID
  36. )
  37. :
  38. CRefCount(MAKE_STAMP_ID('F','T','E','g')),
  39. m_pAppletSession(NULL),
  40. m_eLastSendDataError(T120_NO_ERROR),
  41. m_pMBFTIntf(pMBFTIntf),
  42. m_fConfAvailable(FALSE),
  43. m_fJoinedConf(FALSE),
  44. m_uidMyself(0), // user id
  45. m_nidMyself(0), // node id
  46. m_eidMyself(0), // entity id
  47. m_eMBFTMode(eMode),
  48. m_SessionID(nSessionID),
  49. m_MBFTControlChannel(nSessionID),
  50. m_MBFTDataChannel(0),
  51. m_nRosterInstance(0),
  52. m_nConfID(0),
  53. m_MBFTMaxFileSize(_iMBFT_MAX_FILE_SIZE),
  54. m_MBFTMaxDataPayload(_iMBFT_DEFAULT_MAX_FILEDATA_PDU_LENGTH),
  55. m_MBFTMaxSendDataPayload(_iMBFT_DEFAULT_MAX_MCS_SIZE - _iMBFT_FILEDATA_PDU_SUBTRACT),
  56. m_bV42CompressionSupported(FALSE),
  57. m_v42bisP1(_iMBFT_V42_NO_OF_CODEWORDS),
  58. m_v42bisP2(_iMBFT_V42_MAX_STRING_LENGTH),
  59. // LONCHANC: NetMeeting's Node Controller does not exercise conductorship.
  60. #ifdef ENABLE_CONDUCTORSHIP
  61. m_bInConductedMode(FALSE),
  62. m_ConductorNodeID(0),
  63. m_MBFTConductorID(0),
  64. m_ConductedModePermission(0),
  65. m_bWaitingForPermission(FALSE),
  66. #endif // ENABLE_CONDUCTORSHIP
  67. m_pWindow(NULL),
  68. m_State(IdleNotInitialized)
  69. {
  70. g_fWaitingForBufferAvailable = FALSE;
  71. switch (m_eMBFTMode)
  72. {
  73. case MBFT_STATIC_MODE:
  74. ASSERT(m_MBFTControlChannel == _MBFT_CONTROL_CHANNEL);
  75. m_MBFTDataChannel = _MBFT_DATA_CHANNEL;
  76. break;
  77. #ifdef USE_MULTICAST_SESSION
  78. case MBFT_MULTICAST_MODE:
  79. break;
  80. #endif
  81. default:
  82. ERROR_OUT(("MBFTEngine::MBFTEngine: invalid session type=%u", m_eMBFTMode));
  83. break;
  84. }
  85. // clear join session structures
  86. ::ZeroMemory(&m_aStaticChannels, sizeof(m_aStaticChannels));
  87. #ifdef USE_MULTICAST_SESSION
  88. ::ZeroMemory(&m_aJoinResourceReqs, sizeof(m_aJoinResourceReqs));
  89. #endif
  90. ::ZeroMemory(&m_JoinSessionReq, sizeof(m_JoinSessionReq));
  91. ASSERT(NULL != g_pFileXferApplet);
  92. g_pFileXferApplet->RegisterEngine(this);
  93. m_pWindow = g_pFileXferApplet->GetUnattendedWindow();
  94. if (NULL != m_pWindow)
  95. {
  96. m_pWindow->RegisterEngine(this);
  97. }
  98. #ifdef ENABLE_HEARTBEAT_TIMER
  99. m_nTimerID = ::SetTimer(NULL, 0, IDLE_TIMER_SPEED, HeartBeatTimerProc);
  100. #endif
  101. }
  102. MBFTEngine::~MBFTEngine(void)
  103. {
  104. #ifdef ENABLE_HEARTBEAT_TIMER
  105. // kill the timer now
  106. ::KillTimer(NULL, m_nTimerID);
  107. #endif
  108. // the interface object is already gone
  109. m_pMBFTIntf = NULL;
  110. MBFTSession *pSession;
  111. while (NULL != (pSession = m_SessionList.Get()))
  112. {
  113. pSession->UnInitialize(FALSE);
  114. delete pSession; // LONCHANC: not sure about this delete
  115. }
  116. if (NULL != m_pAppletSession)
  117. {
  118. m_pAppletSession->ReleaseInterface();
  119. }
  120. ASSERT(! m_fJoinedConf);
  121. m_PeerList.DeleteAll();
  122. }
  123. void MBFTEngine::SetInterfacePointer( MBFTInterface *pIntf )
  124. {
  125. CPeerData *pPeerData;
  126. ASSERT (pIntf);
  127. m_pMBFTIntf = pIntf;
  128. m_PeerList.Reset();
  129. while (NULL != (pPeerData = m_PeerList.Iterate()))
  130. {
  131. if (pPeerData->GetNodeID() != m_nidMyself)
  132. {
  133. AddPeerNotification(pPeerData->GetNodeID(),
  134. pPeerData->GetUserID(),
  135. pPeerData->GetIsLocalNode(),
  136. pPeerData->GetIsProshareNode(), TRUE,
  137. pPeerData->GetAppKey(),
  138. m_SessionID);
  139. }
  140. }
  141. }
  142. BOOL MBFTEngine::Has2xNodeInConf(void)
  143. {
  144. CPeerData *pPeerData;
  145. m_PeerList.Reset();
  146. while (NULL != (pPeerData = m_PeerList.Iterate()))
  147. {
  148. // if (pPeerData->GetVersion() < HIWORD(VER_PRODUCTVERSION_DW))
  149. if (pPeerData->GetVersion() < 0x0404)
  150. {
  151. return TRUE;
  152. }
  153. }
  154. return FALSE;
  155. }
  156. BOOL MBFTEngine::HasSDK(void)
  157. {
  158. return (m_pMBFTIntf ? TRUE : FALSE);
  159. }
  160. HRESULT MBFTEngine::SafePostMessage
  161. (
  162. MBFTMsg *pMsg
  163. )
  164. {
  165. if (NULL != pMsg)
  166. {
  167. AddRef();
  168. ::PostMessage(g_pFileXferApplet->GetHiddenWnd(), MBFTMSG_BASIC, (WPARAM) pMsg, (LPARAM) this);
  169. return S_OK;
  170. }
  171. ERROR_OUT(("MBFTEngine::SafePostMessage: null msg ptr"));
  172. return E_OUTOFMEMORY;
  173. }
  174. void MBFTEngine::OnPermitToEnrollIndication
  175. (
  176. GCCAppPermissionToEnrollInd *pInd
  177. )
  178. {
  179. T120Error rc;
  180. TRACEGCC( " Permission to enroll in conference [%d] is %sgranted.\n",
  181. pInd->nConfID, pInd->fPermissionGranted?"":"not " );
  182. m_fConfAvailable = pInd->fPermissionGranted;
  183. if (pInd->fPermissionGranted)
  184. {
  185. m_nConfID = pInd->nConfID;
  186. // build the common part of the join session request for the base session
  187. ASSERT(m_SessionID == m_MBFTControlChannel);
  188. ::ZeroMemory(&m_JoinSessionReq, sizeof(m_JoinSessionReq));
  189. m_JoinSessionReq.dwAttachmentFlags = ATTACHMENT_DISCONNECT_IN_DATA_LOSS;
  190. m_JoinSessionReq.fConductingCapable = FALSE;
  191. m_JoinSessionReq.nStartupChannelType = MCS_STATIC_CHANNEL;
  192. m_JoinSessionReq.cNonCollapsedCaps = sizeof(g_aAppletNonCollCaps) / sizeof(g_aAppletNonCollCaps[0]);
  193. m_JoinSessionReq.apNonCollapsedCaps = (GCCNonCollCap **) &g_aAppletNonCollCaps[0];
  194. m_JoinSessionReq.cCollapsedCaps = sizeof(g_aAppletCaps) / sizeof(g_aAppletCaps[0]);
  195. m_JoinSessionReq.apCollapsedCaps = (GCCAppCap **) &g_aAppletCaps[0];
  196. // put in the session ID which is the control channel ID
  197. m_JoinSessionReq.SessionKey = g_AppletSessionKey;
  198. m_JoinSessionReq.SessionKey.session_id = m_SessionID;
  199. m_aStaticChannels[0] = m_MBFTControlChannel;
  200. // at least one static channel to join
  201. m_JoinSessionReq.aStaticChannels = &m_aStaticChannels[0];
  202. // build the complete join session request for the base session
  203. switch (m_eMBFTMode)
  204. {
  205. case MBFT_STATIC_MODE:
  206. ASSERT(m_MBFTControlChannel == _MBFT_CONTROL_CHANNEL);
  207. ASSERT(m_MBFTDataChannel = _MBFT_DATA_CHANNEL);
  208. m_aStaticChannels[1] = m_MBFTDataChannel;
  209. m_JoinSessionReq.cStaticChannels = 2; // control and data channels
  210. // m_JoinSessionReq.cResourceReqs = 0;
  211. break;
  212. #ifdef USE_MULTICAST_SESSION
  213. case MBFT_MULTICAST_MODE:
  214. m_JoinSessionReq.cStaticChannels = 1; // control channel only
  215. ::ZeroMemory(&m_aJoinResourceReqs, sizeof(m_aJoinResourceReqs));
  216. m_aJoinResourceReqs[0].eCommand = APPLET_RETRIEVE_N_JOIN_CHANNEL;
  217. m_aJoinResourceReqs[0].RegKey.resource_id.length = sizeof(DATA_CHANNEL_RESOURCE_ID) - 1;
  218. m_aJoinResourceReqs[0].RegKey.resource_id.value = DATA_CHANNEL_RESOURCE_ID;
  219. m_aJoinResourceReqs[0].RegKey.session_key = m_JoinSessionReq.SessionKey;
  220. m_JoinSessionReq.cResourceReqs = sizeof(m_aJoinResourceReqs) / sizeof(m_aJoinResourceReqs[0]);
  221. m_JoinSessionReq.aResourceReqs = &m_aJoinResourceReqs[0];
  222. break;
  223. #endif
  224. default:
  225. ERROR_OUT(("MBFTEngine::OnPermitToEnrollIndication: invalid session type=%u", m_eMBFTMode));
  226. break;
  227. }
  228. // now, create the applet session
  229. rc = g_pFileXferApplet->CreateAppletSession(&m_pAppletSession, m_nConfID);
  230. if (T120_NO_ERROR == rc)
  231. {
  232. ASSERT(NULL != m_pAppletSession);
  233. m_pAppletSession->Advise(T120Callback, // callback function
  234. g_pFileXferApplet, // applet context
  235. this); // session context
  236. rc = m_pAppletSession->Join(&m_JoinSessionReq);
  237. }
  238. if (T120_NO_ERROR != rc)
  239. {
  240. WARNING_OUT(("MBFTEngine::OnPermitToEnrollIndication: CreateAppletSession failed, rc=%u", rc));
  241. DBG_SAVE_FILE_LINE
  242. SafePostNotifyMessage(new InitUnInitNotifyMsg(EnumInitFailed));
  243. }
  244. } // in conference
  245. else
  246. // leaving the conference here
  247. {
  248. LPMBFTSESSION pSession;
  249. m_SessionList.Reset();
  250. while (NULL != (pSession = m_SessionList.Iterate()))
  251. {
  252. pSession->UnInitialize( TRUE );
  253. }
  254. //Time to say goodbye...
  255. AddPeerNotification( m_nidMyself, m_uidMyself, TRUE, TRUE, FALSE, MY_APP_STR, m_SessionID );
  256. //Clear the peer list...
  257. m_PeerList.DeleteAll();
  258. //Nuke all sessions except for the first one....
  259. while (NULL != (pSession = m_SessionList.Get()))
  260. {
  261. delete pSession;
  262. }
  263. // leave the conference if not done so
  264. if (NULL != m_pAppletSession)
  265. {
  266. m_pAppletSession->Unadvise();
  267. // LONCHANC: I commented out the following line because we should not
  268. // leave the conference until we are sure that we can release the interface.
  269. // There are outstanding send-data-indication messages. If we leave now,
  270. // we will not be able to free them...
  271. // m_pAppletSession->Leave();
  272. // let the core know we left the conference
  273. DBG_SAVE_FILE_LINE
  274. SafePostNotifyMessage(new InitUnInitNotifyMsg(EnumInvoluntaryUnInit));
  275. }
  276. // we are not in the conference anymore
  277. m_fJoinedConf = FALSE;
  278. // release this engine object in the next tick
  279. ::PostMessage(g_pFileXferApplet->GetHiddenWnd(), MBFTMSG_DELETE_ENGINE, 0, (LPARAM) this);
  280. }
  281. }
  282. void MBFTEngine::OnJoinSessionConfirm
  283. (
  284. T120JoinSessionConfirm *pConfirm
  285. )
  286. {
  287. if (T120_RESULT_SUCCESSFUL == pConfirm->eResult)
  288. {
  289. if (pConfirm->pIAppletSession == m_pAppletSession)
  290. {
  291. m_uidMyself = pConfirm->uidMyself;
  292. m_eidMyself = pConfirm->eidMyself;
  293. m_nidMyself = pConfirm->nidMyself;
  294. ASSERT(m_SessionID == pConfirm->sidMyself);
  295. #ifdef USE_MULTICAST_SESSION
  296. if (MBFT_MULTICAST_MODE == m_eMBFTMode)
  297. {
  298. ASSERT(1 == pConfirm->cResourceReqs);
  299. ASSERT(0 == m_MBFTDataChannel);
  300. ASSERT(APPLET_RETRIEVE_N_JOIN_CHANNEL == pConfirm->aResourceResults[0].eCommand);
  301. m_MBFTDataChannel = pConfirm->aResourceResults[0].nChannelID;
  302. ASSERT(0 != m_MBFTDataChannel);
  303. }
  304. #endif
  305. // we are now officially in the conference
  306. m_fJoinedConf = TRUE;
  307. }
  308. else
  309. {
  310. ERROR_OUT(("MBFTEngine::OnJoinSessionConfirm: not my session confirm, pConfirm->pI=0x%x, m_pI=0x%x", pConfirm->pIAppletSession, m_pAppletSession));
  311. }
  312. }
  313. else
  314. {
  315. WARNING_OUT(("MBFTEngine::OnJoinSessionConfirm: failed, result=%u", pConfirm->eResult));
  316. DBG_SAVE_FILE_LINE
  317. SafePostNotifyMessage(new InitUnInitNotifyMsg(EnumInitFailed));
  318. }
  319. }
  320. CPeerData::CPeerData
  321. (
  322. T120NodeID NodeID,
  323. T120UserID MBFTUserID,
  324. BOOL bIsLocalNode,
  325. BOOL IsProshareNode,
  326. BOOL bCanConduct,
  327. BOOL bEOFAcknowledgment,
  328. LPCSTR lpszAppKey,
  329. DWORD dwVersion
  330. )
  331. :
  332. m_NodeID(NodeID),
  333. m_MBFTUserID(MBFTUserID),
  334. m_bIsLocalNode(bIsLocalNode),
  335. m_bIsProshareNode(IsProshareNode),
  336. m_bCanConduct(bCanConduct),
  337. m_bEOFAcknowledgment(bEOFAcknowledgment),
  338. m_dwVersion(dwVersion)
  339. {
  340. if (lpszAppKey)
  341. {
  342. ::lstrcpynA(m_szAppKey, lpszAppKey, sizeof(m_szAppKey));
  343. }
  344. else
  345. {
  346. m_szAppKey[0] = '\0';
  347. }
  348. }
  349. void MBFTEngine::AddPeerNotification
  350. (
  351. T120NodeID NodeID,
  352. T120UserID MBFTUserID,
  353. BOOL IsLocalNode,
  354. BOOL IsProshareNode,
  355. BOOL bPeerAdded,
  356. LPCSTR lpszAppKey,
  357. T120SessionID SessionID
  358. )
  359. {
  360. DBG_SAVE_FILE_LINE
  361. SafePostNotifyMessage(
  362. new PeerMsg(NodeID, MBFTUserID, IsLocalNode, IsProshareNode,
  363. lpszAppKey, bPeerAdded, SessionID));
  364. }
  365. void MBFTEngine::AddAllPeers(void)
  366. {
  367. T120NodeID nNodeId;
  368. CPeerData *pPeerData;
  369. m_PeerList.Reset();
  370. while (NULL != (pPeerData = m_PeerList.Iterate()))
  371. {
  372. nNodeId = pPeerData->GetNodeID();
  373. if (nNodeId != m_nidMyself)
  374. {
  375. DBG_SAVE_FILE_LINE
  376. SafePostNotifyMessage(new PeerMsg(nNodeId, pPeerData->GetUserID(),
  377. FALSE, pPeerData->GetIsProshareNode(),
  378. pPeerData->GetAppKey(), TRUE, m_SessionID));
  379. }
  380. }
  381. }
  382. // LONCHANC: NetMeeting's Node Controller does not exercise conductorship.
  383. #ifdef ENABLE_CONDUCTORSHIP
  384. void MBFTEngine::OnConductAssignIndication(GCCConductorAssignInd *pInd)
  385. {
  386. m_ConductorNodeID = pInd->nidConductor;
  387. m_MBFTConductorID = 0;
  388. m_ConductedModePermission = 0;
  389. m_bWaitingForPermission = FALSE;
  390. if (m_nidMyself == m_ConductorNodeID)
  391. {
  392. m_ConductedModePermission |= PrivilegeAssignPDU::EnumFileTransfer;
  393. m_ConductedModePermission |= PrivilegeAssignPDU::EnumFileRequest;
  394. m_ConductedModePermission |= PrivilegeAssignPDU::EnumPriority;
  395. m_ConductedModePermission |= PrivilegeAssignPDU::EnumPrivateChannel;
  396. m_ConductedModePermission |= PrivilegeAssignPDU::EnumAbort;
  397. m_ConductedModePermission |= PrivilegeAssignPDU::EnumNonStandard;
  398. }
  399. else
  400. {
  401. CPeerData *lpPeer;
  402. if (NULL != (lpPeer = m_PeerList.Find(m_ConductorNodeID)))
  403. {
  404. if (lpPeer->GetCanConduct())
  405. {
  406. //Now that we have found a conductor on the conducting node,
  407. //our search is over....
  408. m_MBFTConductorID = lpPeer->GetUserID();
  409. }
  410. }
  411. //MBFT 8.11.1
  412. //If there is a change in the conductor, and there is no MBFT conductor at the
  413. //new conducting node, all transactions must cease....
  414. //The m_bInConductedMode flag tells us if we were already in the conducted mode.
  415. if( !m_MBFTConductorID && m_bInConductedMode )
  416. {
  417. //Abort all transactions....
  418. AbortAllSends();
  419. }
  420. }
  421. m_bInConductedMode = TRUE;
  422. }
  423. void MBFTEngine::OnConductReleaseIndication( GCCConferenceID ConfID )
  424. {
  425. m_bInConductedMode = FALSE;
  426. m_ConductorNodeID = 0;
  427. m_MBFTConductorID = 0;
  428. m_ConductedModePermission = 0;
  429. m_bWaitingForPermission = FALSE;
  430. }
  431. void MBFTEngine::OnConductGrantIndication(GCCConductorPermitGrantInd *pInd)
  432. {
  433. UINT Index;
  434. for( Index = 0; Index < pInd->Granted.cNodes; Index++ )
  435. {
  436. if (pInd->Granted.aNodeIDs[Index] == m_nidMyself)
  437. {
  438. if( pInd->fThisNodeIsGranted )
  439. {
  440. m_ConductedModePermission |= PrivilegeAssignPDU::EnumFileTransfer;
  441. m_ConductedModePermission |= PrivilegeAssignPDU::EnumFileRequest;
  442. m_ConductedModePermission |= PrivilegeAssignPDU::EnumPriority;
  443. m_ConductedModePermission |= PrivilegeAssignPDU::EnumPrivateChannel;
  444. m_ConductedModePermission |= PrivilegeAssignPDU::EnumAbort;
  445. m_ConductedModePermission |= PrivilegeAssignPDU::EnumNonStandard;
  446. }
  447. else
  448. {
  449. //TO DO:
  450. //MBFT 8.11.1 and 8.12.1
  451. //If the MBFT provider receives a GCCConductorPermissionGrantIndication
  452. //with permission_flag = FALSE, all privileges are revoked and all
  453. //transactions should be terminated....
  454. m_ConductedModePermission = 0;
  455. AbortAllSends();
  456. }
  457. break;
  458. }
  459. }
  460. }
  461. void MBFTEngine::AbortAllSends(void)
  462. {
  463. if( m_bInConductedMode )
  464. {
  465. MBFTSession *pSession;
  466. m_SessionList.Reset();
  467. while (NULL != (pSession = m_SessionList.Iterate()))
  468. {
  469. if (pSession->GetSessionType() == MBFT_PRIVATE_SEND_TYPE)
  470. {
  471. pSession->OnControlNotification(
  472. _iMBFT_PROSHARE_ALL_FILES,
  473. FileTransferControlMsg::EnumConductorAbortFile,
  474. NULL,
  475. NULL );
  476. }
  477. }
  478. }
  479. }
  480. #endif // ENABLE_CONDUCTORSHIP
  481. void MBFTEngine::OnDetachUserIndication
  482. (
  483. T120UserID mcsUserID,
  484. T120Reason eReason
  485. )
  486. {
  487. TRACEMCS(" Detach User Indication [%u]\n",mcsUserID);
  488. if (mcsUserID == m_uidMyself)
  489. {
  490. m_fJoinedConf = FALSE;
  491. m_pAppletSession->Unadvise();
  492. //Time to say goodbye...
  493. AddPeerNotification(m_nidMyself, m_uidMyself, TRUE, TRUE, FALSE, MY_APP_STR, m_SessionID);
  494. }
  495. }
  496. BOOL MBFTEngine::ProcessMessage(MBFTMsg *pMsg)
  497. {
  498. BOOL bWasHandled = FALSE;
  499. BOOL bBroadcastFileOfferHack = FALSE;
  500. MBFTSession *pSession;
  501. // lonchanc: it is possible that the channel admit indication comes in
  502. // before the session is created. in this case, put the message back to the queue.
  503. if (m_SessionList.IsEmpty())
  504. {
  505. if (EnumMCSChannelAdmitIndicationMsg == pMsg->GetMsgType())
  506. {
  507. return FALSE; // do not delete the message and put it back to the queue
  508. }
  509. }
  510. m_SessionList.Reset();
  511. while (!bWasHandled && NULL != (pSession = m_SessionList.Iterate()))
  512. {
  513. switch (pMsg->GetMsgType())
  514. {
  515. case EnumMCSChannelAdmitIndicationMsg:
  516. if (pSession->IsReceiveSession())
  517. {
  518. MBFTPrivateReceive *pRecvSession = (MBFTPrivateReceive *) pSession;
  519. MCSChannelAdmitIndicationMsg *p = (MCSChannelAdmitIndicationMsg *) pMsg;
  520. //We have to make an exception in the case because we get this
  521. //message before the PrivateChannelInvitePDU() !!!
  522. bWasHandled = pRecvSession->OnMCSChannelAdmitIndication(p->m_wChannelId, p->m_ManagerID);
  523. if(bWasHandled)
  524. {
  525. TRACEMCS(" Channel Admit Indication [%u], Manager [%u]\n", p->m_wChannelId, p->m_ManagerID);
  526. }
  527. }
  528. break;
  529. case EnumMCSChannelExpelIndicationMsg:
  530. if (pSession->IsReceiveSession())
  531. {
  532. MBFTPrivateReceive *pRecvSession = (MBFTPrivateReceive *) pSession;
  533. MCSChannelExpelIndicationMsg *p = (MCSChannelExpelIndicationMsg *) pMsg;
  534. bWasHandled = pRecvSession->OnMCSChannelExpelIndication(p->m_wChannelId, p->m_iReason);
  535. if(bWasHandled)
  536. {
  537. TRACEMCS(" Channel Expel Indication [%u]\n", p->m_wChannelId);
  538. }
  539. }
  540. break;
  541. case EnumMCSChannelJoinConfirmMsg:
  542. {
  543. MCSChannelJoinConfirmMsg *p = (MCSChannelJoinConfirmMsg *) pMsg;
  544. bWasHandled = pSession->OnMCSChannelJoinConfirm(p->m_wChannelId, p->m_bSuccess);
  545. if(bWasHandled)
  546. {
  547. TRACEMCS(" Channel Join Confirm [%u], Success = [%d]\n", p->m_wChannelId, p->m_bSuccess);
  548. }
  549. }
  550. break;
  551. case EnumMCSChannelConveneConfirmMsg:
  552. if (pSession->IsSendSession())
  553. {
  554. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) pSession;
  555. MCSChannelConveneConfirmMsg *p = (MCSChannelConveneConfirmMsg *) pMsg;
  556. bWasHandled = pSendSession->OnMCSChannelConveneConfirm(p->m_wChannelId, p->m_bSuccess);
  557. if(bWasHandled)
  558. {
  559. TRACEMCS(" Channel Convene Confirm [%u], Success = [%d]\n", p->m_wChannelId, p->m_bSuccess);
  560. }
  561. }
  562. break;
  563. case EnumGenericMBFTPDUMsg:
  564. {
  565. MBFTPDUMsg *p = (MBFTPDUMsg *) pMsg;
  566. bWasHandled = DispatchPDUMessage(pSession, p);
  567. //Background on this hack:
  568. //In the broadcast mode, we may get a FileOfferPDU followed by a FileStart
  569. //PDU and may therefore not give the client application sufficient time
  570. //to process the File Offer. Therefore, we make sure that we stop processing
  571. //other messages if we get a broadcast FileOffer...
  572. if(bWasHandled)
  573. {
  574. if (p->m_PDUType == EnumFileOfferPDU)
  575. {
  576. LPFILEOFFERPDU lpNewFileOfferPDU = (LPFILEOFFERPDU) p->m_lpNewPDU;
  577. if(lpNewFileOfferPDU->GetAcknowledge() == 0)
  578. {
  579. bBroadcastFileOfferHack = TRUE;
  580. }
  581. }
  582. }
  583. }
  584. break;
  585. case EnumPeerDeletedMsg:
  586. {
  587. PeerDeletedMsg *p = (PeerDeletedMsg *) pMsg;
  588. pSession->OnPeerDeletedNotification(p->m_lpPeerData);
  589. }
  590. break;
  591. case EnumSubmitFileSendMsg:
  592. {
  593. SubmitFileSendMsg *p = (SubmitFileSendMsg *) pMsg;
  594. if (p->m_EventHandle == pSession->GetEventHandle())
  595. {
  596. if(pSession->GetSessionType() == MBFT_PRIVATE_SEND_TYPE)
  597. {
  598. bWasHandled = TRUE;
  599. ((MBFTPrivateSend *) pSession)->SubmitFileSendRequest(p);
  600. }
  601. }
  602. }
  603. break;
  604. case EnumFileTransferControlMsg:
  605. {
  606. FileTransferControlMsg *p = (FileTransferControlMsg *) pMsg;
  607. if (p->m_EventHandle == pSession->GetEventHandle())
  608. {
  609. bWasHandled = TRUE;
  610. pSession->OnControlNotification(
  611. p->m_hFile,
  612. p->m_ControlCommand,
  613. p->m_szDirectory,
  614. p->m_szFileName);
  615. }
  616. }
  617. break;
  618. default:
  619. ASSERT(0);
  620. break;
  621. } // switch
  622. if(bBroadcastFileOfferHack)
  623. {
  624. TRACE("(MBFT:) BroadcastFileOfferHack detected, aborting message processing\n");
  625. break; //Out of message for loop
  626. }
  627. } //Message for loop
  628. return TRUE; // delete the message
  629. }
  630. #ifdef ENABLE_CONDUCTORSHIP
  631. BOOL MBFTEngine::ConductedModeOK(void)
  632. {
  633. BOOL bReturn = TRUE;
  634. if(m_bInConductedMode)
  635. {
  636. bReturn = (m_ConductedModePermission & PrivilegeRequestPDU::EnumFileTransfer) &&
  637. (m_ConductedModePermission & PrivilegeRequestPDU::EnumPrivateChannel);
  638. }
  639. return(bReturn);
  640. }
  641. #endif // ENABLE_CONDUCTORSHIP
  642. BOOL MBFTEngine::HandleSessionCreation(MBFTMsg *pMsg)
  643. {
  644. switch (pMsg->GetMsgType())
  645. {
  646. case EnumCreateSessionMsg:
  647. {
  648. CreateSessionMsg *p = (CreateSessionMsg *) pMsg;
  649. MBFTSession *lpNewSession = NULL;
  650. MBFTEVENTHANDLE EventHandle = p->m_EventHandle;
  651. T120SessionID SessionID = p->m_SessionID;
  652. #ifdef ENABLE_CONDUCTORSHIP
  653. BOOL bDeleteMessage = TRUE;
  654. #endif
  655. switch (p->m_iSessionType)
  656. {
  657. case MBFT_PRIVATE_SEND_TYPE:
  658. if(m_State == IdleInitialized)
  659. {
  660. if(ConductedModeOK())
  661. {
  662. TRACESTATE(" Creating new acknowledged send session\n");
  663. DBG_SAVE_FILE_LINE
  664. lpNewSession = new MBFTPrivateSend(this,EventHandle,
  665. m_uidMyself,
  666. m_MBFTMaxSendDataPayload);
  667. ASSERT(NULL != lpNewSession);
  668. }
  669. #ifdef ENABLE_CONDUCTORSHIP
  670. else
  671. {
  672. bDeleteMessage = FALSE;
  673. }
  674. #endif
  675. }
  676. else
  677. {
  678. TRACE(" Invalid attempt to create session before initialization\n");
  679. }
  680. break;
  681. case MBFT_PRIVATE_RECV_TYPE:
  682. if(m_State == IdleInitialized)
  683. {
  684. TRACESTATE(" Creating new acknowledge session\n");
  685. DBG_SAVE_FILE_LINE
  686. lpNewSession = new MBFTPrivateReceive(this,
  687. EventHandle,
  688. p->m_ControlChannel,
  689. p->m_DataChannel);
  690. ASSERT(NULL != lpNewSession);
  691. }
  692. else
  693. {
  694. TRACE(" Invalid attempt to create session before initialization\n");
  695. }
  696. break;
  697. case MBFT_BROADCAST_RECV_TYPE:
  698. #ifdef USE_BROADCAST_RECEIVE
  699. if(m_State == IdleInitialized)
  700. {
  701. TRACESTATE(" Creating new broadcast receive session\n");
  702. DBG_SAVE_FILE_LINE
  703. lpNewSession = new MBFTBroadcastReceive(this,
  704. EventHandle,
  705. p->m_ControlChannel,
  706. p->m_DataChannel,
  707. p->m_SenderID,
  708. p->m_FileHandle);
  709. ASSERT(NULL != lpNewSession);
  710. }
  711. else
  712. {
  713. TRACE(" Invalid attempt to create session before initialization\n");
  714. }
  715. #endif // USE_BROADCAST_RECEIVE
  716. break;
  717. default:
  718. ASSERT(0);
  719. break;
  720. } // switch
  721. if (lpNewSession)
  722. {
  723. #ifdef ENABLE_HEARTBEAT_TIMER
  724. if (lpNewSession->IsSendSession())
  725. {
  726. KillTimer(NULL, m_nTimerID);
  727. m_nTimerID = ::SetTimer(NULL, 0, SESSION_TIMER_SPEED, HeartBeatTimerProc);
  728. }
  729. #endif
  730. m_SessionList.Append(lpNewSession);
  731. }
  732. } // if create session message
  733. break;
  734. case EnumDeleteSessionMsg:
  735. {
  736. DeleteSessionMsg *p = (DeleteSessionMsg *) pMsg;
  737. #ifdef ENABLE_HEARTBEAT_TIMER
  738. if (NULL != p->m_lpDeleteSession)
  739. {
  740. if (p->m_lpDeleteSession->IsSendSession())
  741. {
  742. BOOL fSendSessExists = FALSE;
  743. MBFTSession *pSess;
  744. m_SessionList.Reset();
  745. while (NULL != (pSess = m_SessionList.Iterate()))
  746. {
  747. if (pSess->IsSendSession())
  748. {
  749. fSendSessExists = TRUE;
  750. break;
  751. }
  752. }
  753. if (! fSendSessExists)
  754. {
  755. ::KillTimer(NULL, m_nTimerID);
  756. m_nTimerID = ::SetTimer(NULL, 0, IDLE_TIMER_SPEED, HeartBeatTimerProc);
  757. }
  758. }
  759. }
  760. #endif
  761. m_SessionList.Delete(p->m_lpDeleteSession);
  762. } // if delete session message
  763. break;
  764. default:
  765. return FALSE; // not handled
  766. }
  767. return TRUE; // handled
  768. }
  769. BOOL MBFTEngine::DispatchPDUMessage(MBFTSession *lpMBFTSession,MBFTPDUMsg * lpNewMessage)
  770. {
  771. T120ChannelID wChannelID = lpNewMessage->m_wChannelId;
  772. T120Priority iPriority = lpNewMessage->m_iPriority;
  773. T120UserID SenderID = lpNewMessage->m_SenderID;
  774. T120NodeID NodeID = GetNodeIdByUserID(SenderID);
  775. BOOL IsUniformSendData = lpNewMessage->m_IsUniformSendData;
  776. LPGENERICPDU lpNewPDU = lpNewMessage->m_lpNewPDU;
  777. MBFTPDUType DecodedPDUType = lpNewMessage->m_PDUType;
  778. BOOL bWasHandled = FALSE;
  779. ASSERT(NULL != lpNewPDU);
  780. switch(DecodedPDUType)
  781. {
  782. case EnumFileOfferPDU:
  783. if (lpMBFTSession->IsReceiveSession())
  784. {
  785. MBFTPrivateReceive *pRecvSession = (MBFTPrivateReceive *) lpMBFTSession;
  786. bWasHandled = pRecvSession->OnReceivedFileOfferPDU(wChannelID,
  787. iPriority,
  788. SenderID,
  789. NodeID,
  790. (LPFILEOFFERPDU)lpNewPDU,
  791. IsUniformSendData);
  792. if(bWasHandled)
  793. {
  794. TRACEPDU(" File Offer PDU from [%u]\n",SenderID);
  795. }
  796. }
  797. break;
  798. case EnumFileAcceptPDU:
  799. if (lpMBFTSession->IsSendSession())
  800. {
  801. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  802. bWasHandled = pSendSession->OnReceivedFileAcceptPDU(wChannelID,
  803. iPriority,
  804. SenderID,
  805. (LPFILEACCEPTPDU)lpNewPDU,
  806. IsUniformSendData);
  807. if(bWasHandled)
  808. {
  809. TRACEPDU(" File Accept PDU from [%u]\n",SenderID);
  810. }
  811. }
  812. break;
  813. case EnumFileRejectPDU:
  814. if (lpMBFTSession->IsSendSession())
  815. {
  816. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  817. bWasHandled = pSendSession->OnReceivedFileRejectPDU(wChannelID,
  818. iPriority,
  819. SenderID,
  820. (LPFILEREJECTPDU)lpNewPDU,
  821. IsUniformSendData);
  822. if(bWasHandled)
  823. {
  824. TRACEPDU(" File Reject PDU from [%u]\n",SenderID);
  825. }
  826. }
  827. break;
  828. case EnumFileAbortPDU:
  829. #ifdef ENABLE_CONDUCTORSHIP
  830. if(m_bInConductedMode)
  831. {
  832. LPFILEABORTPDU lpAbortPDU = (LPFILEABORTPDU)lpNewPDU;
  833. T120UserID MBFTUserID = lpAbortPDU->GetTransmitterID();
  834. //MBFT 8.11.2
  835. //If no MBFTUserID is specified, all providers must stop transmission...
  836. if(!MBFTUserID)
  837. {
  838. AbortAllSends();
  839. bWasHandled = TRUE;
  840. }
  841. else if(MBFTUserID == m_uidMyself)
  842. {
  843. //If only MBFTUserID is specified, all transmissions by that
  844. //MBFT provider must cease....
  845. if(!lpAbortPDU->GetFileHandle() && !lpAbortPDU->GetDataChannelID())
  846. {
  847. AbortAllSends();
  848. bWasHandled = TRUE;
  849. }
  850. else
  851. {
  852. if (lpMBFTSession->IsSendSession())
  853. {
  854. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  855. bWasHandled = pSendSession->OnReceivedFileAbortPDU(
  856. wChannelID,
  857. iPriority,
  858. SenderID,
  859. (LPFILEABORTPDU)lpNewPDU,
  860. IsUniformSendData);
  861. }
  862. }
  863. }
  864. else
  865. {
  866. //Message was not meant for us...
  867. bWasHandled = TRUE;
  868. }
  869. }
  870. else
  871. #endif // ENABLE_CONDUCTORSHIP
  872. {
  873. bWasHandled = TRUE;
  874. }
  875. if(bWasHandled)
  876. {
  877. TRACEPDU(" File Abort PDU from [%u]\n",SenderID);
  878. }
  879. break;
  880. case EnumFileStartPDU:
  881. if (lpMBFTSession->IsReceiveSession())
  882. {
  883. MBFTPrivateReceive *pRecvSession = (MBFTPrivateReceive *) lpMBFTSession;
  884. bWasHandled = pRecvSession->OnReceivedFileStartPDU(wChannelID,
  885. iPriority,
  886. SenderID,
  887. (LPFILESTARTPDU)lpNewPDU,
  888. IsUniformSendData);
  889. if(bWasHandled)
  890. {
  891. TRACEPDU(" File Start PDU from [%u]\n",SenderID);
  892. }
  893. }
  894. break;
  895. case EnumFileDataPDU:
  896. if (lpMBFTSession->IsReceiveSession())
  897. {
  898. MBFTPrivateReceive *pRecvSession = (MBFTPrivateReceive *) lpMBFTSession;
  899. bWasHandled = pRecvSession->OnReceivedFileDataPDU(wChannelID,
  900. iPriority,
  901. SenderID,
  902. (LPFILEDATAPDU)lpNewPDU,
  903. IsUniformSendData);
  904. if(bWasHandled)
  905. {
  906. TRACEPDU(" File Data PDU from [%u]\n",SenderID);
  907. }
  908. }
  909. break;
  910. case EnumPrivateChannelInvitePDU:
  911. bWasHandled = TRUE;
  912. TRACEPDU(" Private Channel Invite PDU from [%u]\n",SenderID);
  913. break;
  914. case EnumPrivateChannelResponsePDU:
  915. if (lpMBFTSession->IsSendSession())
  916. {
  917. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  918. bWasHandled = pSendSession->OnReceivedPrivateChannelResponsePDU(wChannelID,
  919. iPriority,
  920. SenderID,
  921. (LPPRIVATECHANNELRESPONSEPDU)lpNewPDU,
  922. IsUniformSendData);
  923. if(bWasHandled)
  924. {
  925. TRACEPDU(" Private Channel Response PDU from [%u]\n",SenderID);
  926. }
  927. }
  928. break;
  929. case EnumNonStandardPDU:
  930. if (lpMBFTSession->IsSendSession())
  931. {
  932. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  933. bWasHandled = pSendSession->OnReceivedNonStandardPDU(wChannelID,
  934. iPriority,
  935. SenderID,
  936. (LPNONSTANDARDPDU)lpNewPDU,
  937. IsUniformSendData);
  938. if(bWasHandled)
  939. {
  940. TRACEPDU(" Non Standard PDU from [%u]\n",SenderID);
  941. }
  942. }
  943. break;
  944. case EnumFileErrorPDU:
  945. bWasHandled = lpMBFTSession->OnReceivedFileErrorPDU(wChannelID,
  946. iPriority,
  947. SenderID,
  948. (LPFILEERRORPDU)lpNewPDU,
  949. IsUniformSendData);
  950. if(bWasHandled)
  951. {
  952. TRACEPDU(" File Error PDU from [%u]\n",SenderID);
  953. }
  954. break;
  955. case EnumFileRequestPDU:
  956. bWasHandled = OnReceivedFileRequestPDU(wChannelID,
  957. iPriority,
  958. SenderID,
  959. (LPFILEREQUESTPDU)lpNewPDU,
  960. IsUniformSendData);
  961. if(bWasHandled)
  962. {
  963. TRACEPDU(" File Request PDU from [%u]\n",SenderID);
  964. }
  965. break;
  966. case EnumFileDenyPDU:
  967. TRACE(" *** WARNING (MBFT): Received File Deny PDU from [%u] *** \n",SenderID);
  968. bWasHandled = TRUE;
  969. break;
  970. case EnumDirectoryRequestPDU:
  971. bWasHandled = OnReceivedDirectoryRequestPDU(wChannelID,
  972. iPriority,
  973. SenderID,
  974. (LPDIRECTORYREQUESTPDU)lpNewPDU,
  975. IsUniformSendData);
  976. if(bWasHandled)
  977. {
  978. TRACEPDU(" DirectoryRequest PDU from [%u]\n",SenderID);
  979. }
  980. break;
  981. case EnumDirectoryResponsePDU:
  982. TRACE(" *** WARNING (MBFT): Received Directory Response PDU from [%u] *** \n",SenderID);
  983. bWasHandled = TRUE;
  984. break;
  985. case EnumPrivilegeAssignPDU:
  986. bWasHandled = OnReceivedPrivilegeAssignPDU(wChannelID,
  987. iPriority,
  988. SenderID,
  989. (LPPRIVILEGEASSIGNPDU)lpNewPDU,
  990. IsUniformSendData);
  991. break;
  992. #if 0
  993. //Do not delete this code...
  994. //It may become part of the MBFT standard in the future...
  995. case EnumFileEndAcknowledgePDU:
  996. if (lpMBFTSession->IsSendSession())
  997. {
  998. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  999. bWasHandled = pSendSession->OnReceivedFileEndAcknowledgePDU(wChannelID,
  1000. iPriority,
  1001. SenderID,
  1002. (LPFILEENDACKNOWLEDGEPDU)lpNewPDU,
  1003. IsUniformSendData);
  1004. }
  1005. break;
  1006. case EnumChannelLeavePDU:
  1007. if (lpMBFTSession->IsSendSession())
  1008. {
  1009. MBFTPrivateSend *pSendSession = (MBFTPrivateSend *) lpMBFTSession;
  1010. bWasHandled = pSendSession->OnReceivedChannelLeavePDU(wChannelID,
  1011. iPriority,
  1012. SenderID,
  1013. (LPCHANNELLEAVEPDU)lpNewPDU,
  1014. IsUniformSendData);
  1015. }
  1016. break;
  1017. //Do not delete this code...
  1018. //It may become part of the MBFT standard in the future...
  1019. #endif
  1020. default:
  1021. TRACE(" *** WARNING (MBFT): Unhandled PDU from [%u] *** \n",SenderID);
  1022. bWasHandled = TRUE; // LONCHANC: this should be false, right? why true?
  1023. break;
  1024. } // switch
  1025. return(bWasHandled);
  1026. }
  1027. BOOL MBFTEngine::OnReceivedPrivateChannelInvitePDU(T120ChannelID wChannelID,
  1028. T120Priority iPriority,
  1029. T120UserID SenderID,
  1030. LPPRIVATECHANNELINVITEPDU lpNewPDU,
  1031. BOOL IsUniformSendData)
  1032. {
  1033. if(m_State == IdleInitialized)
  1034. {
  1035. DBG_SAVE_FILE_LINE
  1036. MBFTMsg *pMsg = new CreateSessionMsg(MBFT_PRIVATE_RECV_TYPE,
  1037. ::GetNewEventHandle(),
  1038. 0,
  1039. lpNewPDU->GetControlChannel(),
  1040. lpNewPDU->GetDataChannel());
  1041. if (NULL != pMsg)
  1042. {
  1043. DoStateMachine(pMsg);
  1044. delete pMsg;
  1045. }
  1046. }
  1047. return(TRUE);
  1048. }
  1049. BOOL MBFTEngine::OnReceivedFileRequestPDU(T120ChannelID wChannelId,
  1050. T120Priority iPriority,
  1051. T120UserID SenderID,
  1052. LPFILEREQUESTPDU lpNewPDU,
  1053. BOOL IsUniformSendData)
  1054. {
  1055. BOOL bReturn = FALSE;
  1056. DBG_SAVE_FILE_LINE
  1057. LPFILEDENYPDU lpDenyPDU = new FileDenyPDU(lpNewPDU->GetRequestHandle());
  1058. if(lpDenyPDU)
  1059. {
  1060. if(lpDenyPDU->Encode())
  1061. {
  1062. if (SendDataRequest(SenderID, APPLET_HIGH_PRIORITY,
  1063. (LPBYTE)lpDenyPDU->GetBuffer(),
  1064. lpDenyPDU->GetBufferLength()))
  1065. {
  1066. bReturn = TRUE;
  1067. }
  1068. }
  1069. }
  1070. return(bReturn);
  1071. }
  1072. BOOL MBFTEngine::OnReceivedDirectoryRequestPDU(T120ChannelID wChannelId,
  1073. T120Priority iPriority,
  1074. T120UserID SenderID,
  1075. LPDIRECTORYREQUESTPDU lpNewPDU,
  1076. BOOL IsUniformSendData)
  1077. {
  1078. BOOL bReturn = FALSE;
  1079. DBG_SAVE_FILE_LINE
  1080. LPDIRECTORYRESPONSEPDU lpDirPDU = new DirectoryResponsePDU();
  1081. if(lpDirPDU)
  1082. {
  1083. if(lpDirPDU->Encode())
  1084. {
  1085. if (SendDataRequest(SenderID, APPLET_HIGH_PRIORITY,
  1086. (LPBYTE)lpDirPDU->GetBuffer(),
  1087. lpDirPDU->GetBufferLength()))
  1088. {
  1089. bReturn = TRUE;
  1090. }
  1091. }
  1092. }
  1093. return(bReturn);
  1094. }
  1095. BOOL MBFTEngine::OnReceivedPrivilegeAssignPDU(T120ChannelID wChannelId,
  1096. T120Priority iPriority,
  1097. T120UserID SenderID,
  1098. LPPRIVILEGEASSIGNPDU lpNewPDU,
  1099. BOOL IsUniformSendData)
  1100. {
  1101. #ifdef ENABLE_CONDUCTORSHIP
  1102. if(m_bInConductedMode)
  1103. {
  1104. m_ConductedModePermission = lpNewPDU->GetPrivilegeWord();
  1105. }
  1106. #endif
  1107. return(TRUE);
  1108. }
  1109. #ifdef ENABLE_CONDUCTORSHIP
  1110. void MBFTEngine::ApplyForPermission(void)
  1111. {
  1112. //m_bWaitingForPermission is set to make sure that we don't keep
  1113. //reapplying for permission until the conductor changes...
  1114. if(!m_bWaitingForPermission && m_bInConductedMode)
  1115. {
  1116. //MBFT 8.11.1
  1117. //If there is a MBFT conductor at the conducting node, we send
  1118. //a PrivilegeRequestPDU to the conductor....
  1119. if(m_MBFTConductorID)
  1120. {
  1121. DBG_SAVE_FILE_LINE
  1122. PrivilegeRequestPDU * lpNewPDU = new PrivilegeRequestPDU(PrivilegeRequestPDU::EnumFileTransfer |
  1123. PrivilegeRequestPDU::EnumPrivateChannel |
  1124. PrivilegeRequestPDU::EnumNonStandard);
  1125. if(lpNewPDU)
  1126. {
  1127. if(lpNewPDU->Encode())
  1128. {
  1129. if (SendDataRequest(m_MBFTConductorID, APPLET_HIGH_PRIORITY,
  1130. (LPBYTE)lpNewPDU->GetBuffer(),
  1131. lpNewPDU->GetBufferLength()))
  1132. {
  1133. m_bWaitingForPermission = TRUE;
  1134. }
  1135. }
  1136. delete lpNewPDU;
  1137. }
  1138. }
  1139. else
  1140. {
  1141. //MBFT 8.11.2
  1142. //Ask for permission via Node Controller...
  1143. }
  1144. }
  1145. }
  1146. #endif // ENABLE_CONDUCTORSHIP
  1147. BOOL MBFTEngine::DoStateMachine(MBFTMsg *pMsg)
  1148. {
  1149. BOOL fDeleteThisMessage = TRUE;
  1150. if (m_fConfAvailable)
  1151. {
  1152. BOOL fHandled = (NULL != pMsg) ? HandleSessionCreation(pMsg) : FALSE;
  1153. #ifdef ENABLE_CONDUCTORSHIP
  1154. //Logic: If we are in the conducted mode, we check to see if
  1155. // we have sufficient privileges. If not, we make
  1156. // an attempt to secure the requisite privileges....
  1157. if(m_bInConductedMode)
  1158. {
  1159. if(!ConductedModeOK())
  1160. {
  1161. if(!m_bWaitingForPermission)
  1162. {
  1163. ApplyForPermission();
  1164. }
  1165. }
  1166. }
  1167. #endif // ENABLE_CONDUCTORSHIP
  1168. if (NULL != pMsg && ! fHandled)
  1169. {
  1170. fDeleteThisMessage = ProcessMessage(pMsg);
  1171. }
  1172. if (m_State == IdleInitialized && ! m_SessionList.IsEmpty())
  1173. {
  1174. CSessionList SessionListCopy(&m_SessionList);
  1175. MBFTSession *pSession;
  1176. while (NULL != (pSession = SessionListCopy.Get()))
  1177. {
  1178. pSession->DoStateMachine();
  1179. }
  1180. }
  1181. }
  1182. return fDeleteThisMessage;
  1183. }
  1184. //
  1185. // T120 Callback
  1186. //
  1187. void MBFTEngine::OnSendDataIndication
  1188. (
  1189. BOOL IsUniformSendData,
  1190. T120UserID SenderID,
  1191. T120ChannelID wChannelID,
  1192. T120Priority iPriority,
  1193. ULONG ulDataLength,
  1194. LPBYTE lpBuffer
  1195. )
  1196. {
  1197. GenericPDU * lpNewPDU = NULL;
  1198. LPCSTR lpDecodeBuffer = NULL;
  1199. BOOL bAddToPendingList = FALSE;
  1200. {
  1201. MBFTPDUType DecodedPDUType = GenericPDU::DecodePDU(
  1202. (LPSTR) lpBuffer,
  1203. ulDataLength,
  1204. &lpNewPDU,
  1205. &lpDecodeBuffer,
  1206. m_uidMyself,
  1207. m_pAppletSession);
  1208. if(DecodedPDUType != EnumUnknownPDU)
  1209. {
  1210. ASSERT (m_pAppletSession != NULL);
  1211. DBG_SAVE_FILE_LINE
  1212. MBFTPDUMsg * lpNewMessage = new MBFTPDUMsg(wChannelID,
  1213. iPriority,
  1214. SenderID,
  1215. lpNewPDU,
  1216. IsUniformSendData,
  1217. DecodedPDUType,
  1218. (LPSTR)lpDecodeBuffer);
  1219. //Now that we have received a valid PDU, we must make sure that
  1220. //we know about this particular MBFT peer. If not, we add the PDU
  1221. //message to a different list....
  1222. if(IsValidPeerID(SenderID) && m_State == IdleInitialized)
  1223. {
  1224. //If the FileOffer is received on the default Control channel, it
  1225. //cannot be a private subsession send. Therefore, we create a special
  1226. //receive session to handle this case....
  1227. #ifdef USE_BROADCAST_RECEIVE
  1228. if(DecodedPDUType == EnumFileOfferPDU && wChannelID == m_MBFTControlChannel)
  1229. {
  1230. FileOfferPDU * lpFileOffer = (FileOfferPDU *)lpNewPDU;
  1231. DBG_SAVE_FILE_LINE
  1232. MBFTMsg *pMsg = new CreateSessionMsg(MBFT_BROADCAST_RECV_TYPE,
  1233. ::GetNewEventHandle(),
  1234. 0,
  1235. m_MBFTControlChannel,
  1236. lpFileOffer->GetDataChannelID(),
  1237. SenderID,
  1238. lpFileOffer->GetFileHandle());
  1239. if (NULL != pMsg)
  1240. {
  1241. DoStateMachine(pMsg);
  1242. delete pMsg;
  1243. }
  1244. }
  1245. else
  1246. #endif // USE_BROADCAST_RECEIVE
  1247. if(DecodedPDUType == EnumPrivateChannelInvitePDU && wChannelID == m_uidMyself)
  1248. {
  1249. //In theory, the PrivateChannelInvitePDU marks the beginning of
  1250. //a PrivateSubsession receive. Therefore, we create one to handle all subsequent
  1251. //notifications....
  1252. OnReceivedPrivateChannelInvitePDU(wChannelID,
  1253. iPriority,
  1254. SenderID,
  1255. (LPPRIVATECHANNELINVITEPDU)lpNewPDU,
  1256. IsUniformSendData);
  1257. }
  1258. SafePostMessage(lpNewMessage);
  1259. } // if(IsValidPeerID(SenderID))
  1260. else
  1261. {
  1262. WARNING_OUT((" Received PDU from unknown peer [%u], adding to pending message list\n", (UINT) SenderID));
  1263. delete lpNewMessage;
  1264. }
  1265. }
  1266. else
  1267. {
  1268. TRACE(" PDU Decoding Error or Invalid PDU\n");
  1269. }
  1270. // Unless this is one of the special 3 types of PDUs, we also
  1271. // need to free the MCS buffer. In the 3 special cases, the PDUs
  1272. // are responsible for freeing the buffer when they are done.
  1273. if ((DecodedPDUType != EnumFileDataPDU) &&
  1274. (DecodedPDUType != EnumNonStandardPDU) &&
  1275. (DecodedPDUType != EnumFileStartPDU))
  1276. {
  1277. m_pAppletSession->FreeSendDataBuffer((void *) lpBuffer);
  1278. }
  1279. }
  1280. }
  1281. void MBFTEngine::OnRosterReportIndication
  1282. (
  1283. ULONG cRosters,
  1284. GCCAppRoster *aAppRosters[] // array, size_is(cRosters)
  1285. )
  1286. {
  1287. TRACEGCC(" RosterReport: Session count %u\n", (UINT) cRosters);
  1288. UINT Index, PeerIndex, CapIndex;
  1289. LPCSTR lpszAppKey = NULL;
  1290. BOOL fConductorFound = FALSE;
  1291. CPeerList NewPeerList;
  1292. CPeerData *pOldPeer;
  1293. if (0 == cRosters) // not bloody likely
  1294. {
  1295. return;
  1296. }
  1297. for (Index = 0; Index < cRosters; Index++ )
  1298. {
  1299. GCCAppRoster *pRoster = aAppRosters[Index];
  1300. if (pRoster->session_key.session_id != m_SessionID)
  1301. {
  1302. // this roster is not for our session...ignore it
  1303. continue;
  1304. }
  1305. //Added by Atul on 7/18 to fix missing roster instance bug...
  1306. m_nRosterInstance = pRoster->instance_number;
  1307. TRACEGCC( " Peer count [%u]\n", (UINT) pRoster->number_of_records );
  1308. for (PeerIndex = 0; PeerIndex < pRoster->number_of_records; PeerIndex++)
  1309. {
  1310. GCCAppRecord *pRecord = pRoster->application_record_list[PeerIndex];
  1311. lpszAppKey = NULL;
  1312. TRACE( "Local Entity ID [%u], Entity ID [%u], Node ID [%u], MBFTUser ID [%u]\n",
  1313. (UINT) m_eidMyself,
  1314. (UINT) pRecord->entity_id,
  1315. (UINT) pRecord->node_id,
  1316. (UINT) pRecord->application_user_id );
  1317. BOOL IsProshareNode = FALSE;
  1318. BOOL bEOFAcknowledgment = FALSE;
  1319. if (0 == Index)
  1320. {
  1321. for (CapIndex=0; CapIndex < pRoster->number_of_capabilities; CapIndex++)
  1322. {
  1323. GCCAppCap *pCap = pRoster->capabilities_list[CapIndex];
  1324. if (GCC_STANDARD_CAPABILITY != pCap->capability_id.capability_id_type)
  1325. {
  1326. continue;
  1327. }
  1328. switch (pCap->capability_id.standard_capability)
  1329. {
  1330. case _MBFT_MAX_FILE_SIZE_ID:
  1331. m_MBFTMaxFileSize = pCap->capability_class.nMinOrMax;
  1332. TRACEGCC( "max file size set to %u\n", (UINT) m_MBFTMaxFileSize );
  1333. break;
  1334. case _MBFT_MAX_DATA_PAYLOAD_ID:
  1335. m_MBFTMaxDataPayload = _iMBFT_DEFAULT_MAX_FILEDATA_PDU_LENGTH;
  1336. if (pCap->number_of_entities == pRoster->number_of_records)
  1337. {
  1338. m_MBFTMaxDataPayload = pCap->capability_class.nMinOrMax;
  1339. }
  1340. TRACEGCC( "max data payload set to %u\n", (UINT) m_MBFTMaxDataPayload );
  1341. break;
  1342. case _MBFT_V42_COMPRESSION_ID:
  1343. m_bV42CompressionSupported = (BOOL) (pCap->number_of_entities == pRoster->number_of_records);
  1344. TRACEGCC( "V.42bis compression is now %ssupported\n", m_bV42CompressionSupported ? "" : "not " );
  1345. break;
  1346. }
  1347. } // for CapIndex
  1348. } // if 0 == Index
  1349. // TODO: only check for 'ProShare node' if this node is new to us
  1350. for (CapIndex = 0; CapIndex < pRecord->number_of_non_collapsed_caps; CapIndex++)
  1351. {
  1352. GCCNonCollCap *pCap2 = pRecord->non_collapsed_caps_list[CapIndex];
  1353. if (GCC_STANDARD_CAPABILITY == pCap2->capability_id.capability_id_type)
  1354. {
  1355. if (_iMBFT_FIRST_PROSHARE_CAPABILITY_ID == pCap2->capability_id.standard_capability)
  1356. {
  1357. LPSTR pszData = (LPSTR) pCap2->application_data->value;
  1358. if (pCap2->application_data->length > sizeof(PROSHARE_STRING))
  1359. {
  1360. if (0 == ::memcmp(pszData, PROSHARE_STRING, sizeof(PROSHARE_STRING)))
  1361. {
  1362. IsProshareNode = TRUE;
  1363. lpszAppKey = &pszData[sizeof(PROSHARE_STRING)];
  1364. }
  1365. }
  1366. }
  1367. else
  1368. if (_iMBFT_PROSHARE_FILE_EOF_ACK_ID == pCap2->capability_id.standard_capability)
  1369. {
  1370. LPSTR pszData = (LPSTR) pCap2->application_data->value;
  1371. if (pCap2->application_data->length >= sizeof(PROSHARE_FILE_END_STRING) - 1)
  1372. {
  1373. if (0 == ::memcmp(pszData, PROSHARE_FILE_END_STRING, sizeof(PROSHARE_FILE_END_STRING) - 1))
  1374. {
  1375. bEOFAcknowledgment = TRUE;
  1376. }
  1377. }
  1378. }
  1379. } // if std cap
  1380. } // for CapIndex
  1381. BOOL IsLocalNode = (m_eidMyself == pRecord->entity_id) && (m_nidMyself == pRecord->node_id);
  1382. if( ( IdleNotInitialized == m_State )
  1383. && IsLocalNode
  1384. && pRecord->is_enrolled_actively )
  1385. {
  1386. m_State = IdleInitialized;
  1387. // m_uidMyself = pRecord->application_user_id;
  1388. m_MBFTControlChannel = m_SessionID;
  1389. }
  1390. #ifdef ENABLE_CONDUCTORSHIP
  1391. if( m_bInConductedMode )
  1392. {
  1393. if (pRecord->node_id == m_ConductorNodeID &&
  1394. pRecord->is_conducting_capable)
  1395. {
  1396. //Now that we have found a conductor on the conducting node,
  1397. //our search is over....
  1398. //Make sure that the previously assigned conductor is still
  1399. //present in the roster report...
  1400. if( m_MBFTConductorID )
  1401. {
  1402. if( m_MBFTConductorID == pRecord->application_user_id )
  1403. {
  1404. fConductorFound = TRUE;
  1405. break;
  1406. }
  1407. }
  1408. else
  1409. {
  1410. //First time conductor assignment.....
  1411. m_MBFTConductorID = pRecord->application_user_id;
  1412. fConductorFound = TRUE;
  1413. if(m_ConductorNodeID != m_nidMyself)
  1414. {
  1415. m_ConductedModePermission = 0;
  1416. m_bWaitingForPermission = FALSE;
  1417. }
  1418. break;
  1419. }
  1420. }
  1421. }
  1422. #endif // ENABLE_CONDUCTORSHIP
  1423. // build a new peer list
  1424. if (pRecord->is_enrolled_actively)
  1425. {
  1426. DBG_SAVE_FILE_LINE
  1427. CPeerData *lpPeer = new CPeerData(
  1428. pRecord->node_id,
  1429. pRecord->application_user_id,
  1430. IsLocalNode,
  1431. IsProshareNode,
  1432. pRecord->is_conducting_capable,
  1433. bEOFAcknowledgment,
  1434. lpszAppKey,
  1435. (DWORD)((pRecord->node_id == m_nidMyself)?((VER_PRODUCTVERSION_DW&0xffff0000)>>16):
  1436. T120_GetNodeVersion(m_nConfID, pRecord->node_id)));
  1437. if (NULL == lpPeer)
  1438. {
  1439. ASSERT(0);
  1440. return;
  1441. }
  1442. NewPeerList.Append(lpPeer);
  1443. pOldPeer = m_PeerList.FindSamePeer(lpPeer);
  1444. if (NULL != pOldPeer)
  1445. {
  1446. // we already new about this peer
  1447. m_PeerList.Delete(pOldPeer);
  1448. }
  1449. else
  1450. {
  1451. // this is a new peer
  1452. AddPeerNotification(
  1453. pRecord->node_id,
  1454. pRecord->application_user_id,
  1455. IsLocalNode,
  1456. IsProshareNode,
  1457. TRUE,
  1458. lpszAppKey ? lpszAppKey : "", // TODO: address appkey issue here; needed?
  1459. pRoster->session_key.session_id );
  1460. }
  1461. }
  1462. }
  1463. }
  1464. #ifdef ENABLE_CONDUCTORSHIP
  1465. //If we are on the conducting node, we need no privileges...
  1466. if (m_bInConductedMode && (m_ConductorNodeID != m_nidMyself))
  1467. {
  1468. //MBFT 8.11.1
  1469. //If the previously assigned conductor is not present in the roster report,
  1470. //all privileges are revoked and we should abort all sends...
  1471. if( !fConductorFound )
  1472. {
  1473. AbortAllSends();
  1474. }
  1475. }
  1476. #endif // ENABLE_CONDUCTORSHIP
  1477. while (NULL != (pOldPeer = m_PeerList.Get()))
  1478. {
  1479. AddPeerNotification(
  1480. pOldPeer->GetNodeID(),
  1481. pOldPeer->GetUserID(),
  1482. pOldPeer->GetIsLocalNode(),
  1483. pOldPeer->GetIsProshareNode(),
  1484. FALSE,
  1485. MY_APP_STR,
  1486. m_SessionID );
  1487. DBG_SAVE_FILE_LINE
  1488. CPeerData *p = new CPeerData(
  1489. pOldPeer->GetNodeID(),
  1490. pOldPeer->GetUserID(),
  1491. pOldPeer->GetIsLocalNode(),
  1492. pOldPeer->GetIsProshareNode(),
  1493. pOldPeer->GetCanConduct(),
  1494. pOldPeer->GetEOFAcknowledge(),
  1495. pOldPeer->GetAppKey(),
  1496. pOldPeer->GetVersion());
  1497. ASSERT(NULL != p);
  1498. if (p)
  1499. {
  1500. DBG_SAVE_FILE_LINE
  1501. SafePostMessage(new PeerDeletedMsg(p));
  1502. }
  1503. TRACEGCC("Peer Removed: Node [%u], UserID [%u]\n", pOldPeer->GetNodeID(), pOldPeer->GetUserID() );
  1504. delete pOldPeer;
  1505. }
  1506. while (NULL != (pOldPeer = NewPeerList.Get()))
  1507. {
  1508. m_PeerList.Append(pOldPeer);
  1509. }
  1510. // notify UI of new rosters
  1511. if (NULL != m_pWindow)
  1512. {
  1513. m_pWindow->UpdateUI();
  1514. }
  1515. }
  1516. void MBFTEngine::OnChannelAdmitIndication
  1517. (
  1518. T120ChannelID nChannelID,
  1519. T120UserID nManagerID
  1520. )
  1521. {
  1522. if (IsValidPeerID(nManagerID) && m_State == IdleInitialized)
  1523. {
  1524. DBG_SAVE_FILE_LINE
  1525. SafePostMessage(new MCSChannelAdmitIndicationMsg(nChannelID, nManagerID));
  1526. }
  1527. }
  1528. void CALLBACK T120Callback
  1529. (
  1530. T120AppletSessionMsg *pMsg
  1531. )
  1532. {
  1533. MBFTEngine *pEngine = (MBFTEngine *) pMsg->pSessionContext;
  1534. ASSERT(NULL != pEngine);
  1535. BOOL fSuccess;
  1536. T120ChannelID nChannelID;
  1537. switch (pMsg->eMsgType)
  1538. {
  1539. case T120_JOIN_SESSION_CONFIRM:
  1540. pEngine->OnJoinSessionConfirm(&pMsg->JoinSessionConfirm);
  1541. break;
  1542. case GCC_APP_ROSTER_REPORT_INDICATION:
  1543. pEngine->OnRosterReportIndication(pMsg->AppRosterReportInd.cRosters,
  1544. pMsg->AppRosterReportInd.apAppRosters);
  1545. break;
  1546. // case GCC_APPLICATION_INVOKE_CONFIRM:
  1547. // break;
  1548. case MCS_SEND_DATA_INDICATION:
  1549. case MCS_UNIFORM_SEND_DATA_INDICATION:
  1550. pEngine->OnSendDataIndication(
  1551. (pMsg->eMsgType == MCS_UNIFORM_SEND_DATA_INDICATION),
  1552. pMsg->SendDataInd.initiator,
  1553. pMsg->SendDataInd.channel_id,
  1554. (T120Priority) pMsg->SendDataInd.data_priority,
  1555. pMsg->SendDataInd.user_data.length,
  1556. pMsg->SendDataInd.user_data.value);
  1557. break;
  1558. case MCS_CHANNEL_JOIN_CONFIRM:
  1559. fSuccess = (T120_RESULT_SUCCESSFUL == pMsg->ChannelConfirm.eResult);
  1560. DBG_SAVE_FILE_LINE
  1561. pEngine->SafePostMessage(new MCSChannelJoinConfirmMsg(pMsg->ChannelConfirm.nChannelID, fSuccess));
  1562. break;
  1563. case MCS_CHANNEL_CONVENE_CONFIRM:
  1564. fSuccess = (T120_RESULT_SUCCESSFUL == pMsg->ChannelConfirm.eResult);
  1565. DBG_SAVE_FILE_LINE
  1566. pEngine->SafePostMessage(new MCSChannelConveneConfirmMsg(pMsg->ChannelConfirm.nChannelID, fSuccess));
  1567. break;
  1568. // case MCS_CHANNEL_LEAVE_INDICATION:
  1569. // break;
  1570. // case MCS_CHANNEL_DISBAND_INDICATION:
  1571. // break;
  1572. case MCS_CHANNEL_ADMIT_INDICATION:
  1573. pEngine->OnChannelAdmitIndication(pMsg->ChannelInd.nChannelID, pMsg->ChannelInd.nManagerID);
  1574. break;
  1575. case MCS_CHANNEL_EXPEL_INDICATION:
  1576. DBG_SAVE_FILE_LINE
  1577. pEngine->SafePostMessage(new MCSChannelExpelIndicationMsg(pMsg->ChannelInd.nChannelID, pMsg->ChannelInd.eReason));
  1578. break;
  1579. // case MCS_TOKEN_GRAB_CONFIRM:
  1580. // case MCS_TOKEN_INHIBIT_CONFIRM:
  1581. // case MCS_TOKEN_GIVE_CONFIRM:
  1582. // case MCS_TOKEN_RELEASE_CONFIRM:
  1583. // case MCS_TOKEN_TEST_CONFIRM:
  1584. // break;
  1585. // case MCS_TOKEN_GIVE_INDICATION:
  1586. // case MCS_TOKEN_PLEASE_INDICATION:
  1587. // case MCS_TOKEN_RELEASE_INDICATION:
  1588. // break;
  1589. case MCS_DETACH_USER_INDICATION:
  1590. pEngine->OnDetachUserIndication(pMsg->DetachUserInd.nUserID, pMsg->DetachUserInd.eReason);
  1591. break;
  1592. case MCS_TRANSMIT_BUFFER_AVAILABLE_INDICATION:
  1593. g_fWaitingForBufferAvailable = FALSE;
  1594. ::PostMessage(g_pFileXferApplet->GetHiddenWnd(),
  1595. MBFTMSG_HEART_BEAT, 0, (LPARAM) pEngine);
  1596. break;
  1597. }
  1598. }
  1599. BOOL MBFTEngine::SimpleChannelRequest
  1600. (
  1601. AppletChannelCommand eCommand,
  1602. T120ChannelID nChannelID
  1603. )
  1604. {
  1605. T120ChannelRequest req;
  1606. ::ZeroMemory(&req, sizeof(req));
  1607. req.eCommand = eCommand;
  1608. req.nChannelID = nChannelID;
  1609. T120Error rc = m_pAppletSession->ChannelRequest(&req);
  1610. return (T120_NO_ERROR == rc);
  1611. }
  1612. T120NodeID MBFTEngine::GetNodeIdByUserID(T120UserID nUserID)
  1613. {
  1614. CPeerData *p;
  1615. m_PeerList.Reset();
  1616. while (NULL != (p = m_PeerList.Iterate()))
  1617. {
  1618. if (nUserID == p->GetUserID())
  1619. {
  1620. return p->GetNodeID();
  1621. }
  1622. }
  1623. return 0;
  1624. }
  1625. BOOL MBFTEngine::MCSChannelAdmitRequest
  1626. (
  1627. T120ChannelID nChannelID,
  1628. T120UserID *aUsers,
  1629. ULONG cUsers
  1630. )
  1631. {
  1632. T120ChannelRequest req;
  1633. ::ZeroMemory(&req, sizeof(req));
  1634. req.eCommand = APPLET_ADMIT_CHANNEL;
  1635. req.nChannelID = nChannelID;
  1636. req.cUsers = cUsers;
  1637. req.aUsers = aUsers;
  1638. T120Error rc = m_pAppletSession->ChannelRequest(&req);
  1639. return (T120_NO_ERROR == rc);
  1640. }
  1641. BOOL MBFTEngine::SendDataRequest
  1642. (
  1643. T120ChannelID nChannelID,
  1644. T120Priority ePriority,
  1645. LPBYTE pBuffer,
  1646. ULONG cbBufSize
  1647. )
  1648. {
  1649. if (m_eLastSendDataError == MCS_TRANSMIT_BUFFER_FULL)
  1650. {
  1651. if (g_fWaitingForBufferAvailable == FALSE)
  1652. {
  1653. m_eLastSendDataError = MCS_NO_ERROR;
  1654. }
  1655. else
  1656. {
  1657. TRACEMCS("MBFTEngine::SendDataReques still waiting for a MCS_TRANSMIT_BUFFER_AVAILABLE_INDICATION");
  1658. return FALSE;
  1659. }
  1660. }
  1661. m_eLastSendDataError = m_pAppletSession->SendData(
  1662. NORMAL_SEND_DATA, nChannelID, ePriority,
  1663. pBuffer, cbBufSize, APP_ALLOCATION);
  1664. //
  1665. // T120 is busy and can't allocate data
  1666. //
  1667. if (m_eLastSendDataError == MCS_TRANSMIT_BUFFER_FULL)
  1668. {
  1669. g_fWaitingForBufferAvailable = TRUE;
  1670. TRACEMCS("MCSSendDataRequest failed we will not send data until we get a MCS_TRANSMIT_BUFFER_AVAILABLE_INDICATION");
  1671. }
  1672. return (T120_NO_ERROR == m_eLastSendDataError);
  1673. }
  1674. //
  1675. // CPeerList
  1676. //
  1677. CPeerData * CPeerList::Find(T120NodeID nNodeID)
  1678. {
  1679. CPeerData *p;
  1680. Reset();
  1681. while (NULL != (p = Iterate()))
  1682. {
  1683. if (p->GetUserID() == nNodeID)
  1684. {
  1685. return p;
  1686. }
  1687. }
  1688. return NULL;
  1689. }
  1690. CPeerData * CPeerList::FindSamePeer(CPeerData *pPeer)
  1691. {
  1692. CPeerData *p;
  1693. Reset();
  1694. while (NULL != (p = Iterate()))
  1695. {
  1696. if (pPeer->GetNodeID() == p->GetNodeID() && pPeer->GetUserID() == p->GetUserID())
  1697. {
  1698. return p;
  1699. }
  1700. }
  1701. return NULL;
  1702. }
  1703. void CPeerList::Delete(CPeerData *p)
  1704. {
  1705. if (Remove(p))
  1706. {
  1707. delete p;
  1708. }
  1709. }
  1710. void CPeerList::DeleteAll(void)
  1711. {
  1712. CPeerData *p;
  1713. while (NULL != (p = Get()))
  1714. {
  1715. delete p;
  1716. }
  1717. }
  1718. void CSessionList::Delete(MBFTSession *p)
  1719. {
  1720. if (Remove(p))
  1721. {
  1722. delete p;
  1723. }
  1724. }
  1725. // thought it is a pure virtual, we still need a destructor
  1726. MBFTSession::~MBFTSession(void) { }
  1727. HRESULT MBFTEngine::SafePostNotifyMessage(MBFTMsg *p)
  1728. {
  1729. // notify applet UI if it exists
  1730. if (NULL != m_pWindow)
  1731. {
  1732. m_pWindow->OnEngineNotify(p);
  1733. }
  1734. if (NULL != m_pMBFTIntf)
  1735. {
  1736. return m_pMBFTIntf->SafePostNotifyMessage(p);
  1737. }
  1738. delete p;
  1739. return S_OK;
  1740. }
  1741. MBFTEVENTHANDLE GetNewEventHandle(void)
  1742. {
  1743. static ULONG s_nEventHandle = 0x55AA;
  1744. ULONG nEvtHdl;
  1745. ::EnterCriticalSection(&g_csWorkThread);
  1746. if (s_nEventHandle > 0xFFFF)
  1747. {
  1748. s_nEventHandle = 0x55AA;
  1749. }
  1750. nEvtHdl = s_nEventHandle++;
  1751. ::LeaveCriticalSection(&g_csWorkThread);
  1752. return nEvtHdl;
  1753. }
  1754. MBFTFILEHANDLE GetNewFileHandle(void)
  1755. {
  1756. static ULONG s_nFileHandle = 1;
  1757. ULONG nFileHdl;
  1758. ::EnterCriticalSection(&g_csWorkThread);
  1759. if (s_nFileHandle > 0xFFFF)
  1760. {
  1761. s_nFileHandle = 0x1;
  1762. }
  1763. nFileHdl = s_nFileHandle++;
  1764. ::LeaveCriticalSection(&g_csWorkThread);
  1765. return nFileHdl;
  1766. }