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.

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