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.

1866 lines
48 KiB

  1. // File: ichnldat.cpp
  2. //
  3. // INmChannelData
  4. //
  5. #include "precomp.h"
  6. #include <wbguid.h>
  7. #include <confguid.h>
  8. #include "pfnt120.h"
  9. #include "ichnldat.h"
  10. static const IID * g_apiidCP[] =
  11. {
  12. {&IID_INmChannelDataNotify2},
  13. {&IID_INmChannelDataNotify},
  14. {&IID_INmChannelNotify}
  15. };
  16. #define CopyStruct(pDest, pSrc) CopyMemory(pDest, pSrc, sizeof(*(pDest)))
  17. #define MAX_NM_PEER 256 // Maximum number of NetMeeting Peer applications/users
  18. #ifdef DEBUG /* T.120 Debug utilities */
  19. LPCTSTR GetGccErrorString(GCCError uErr);
  20. LPCTSTR GetMcsErrorString(MCSError uErr);
  21. LPCTSTR GetGccResultString(UINT uErr);
  22. LPCTSTR GetMcsResultString(UINT uErr);
  23. #else
  24. #define GetGccErrorString(uErr) ""
  25. #define GetMcsErrorString(uErr) ""
  26. #define GetGccResultString(uErr) ""
  27. #define GetMcsResultString(uErr) ""
  28. #endif /* DEBUG */
  29. // code from nm\ui\conf\cuserdta.cpp:
  30. static unsigned char H221IDGUID[5] = {H221GUIDKEY0,
  31. H221GUIDKEY1,
  32. H221GUIDKEY2,
  33. H221GUIDKEY3,
  34. H221GUIDKEY4};
  35. // Create an H.221 application key with a guid
  36. VOID NMINTERNAL CreateH221AppKeyFromGuid(LPBYTE lpb, GUID * pguid)
  37. {
  38. CopyMemory(lpb, H221IDGUID, sizeof(H221IDGUID));
  39. CopyMemory(lpb + sizeof(H221IDGUID), pguid, sizeof(GUID));
  40. }
  41. /* S E T A P P K E Y */
  42. /*----------------------------------------------------------------------------
  43. %%Function: SetAppKey
  44. Set the two pieces of an OctetString (the length and the data.)
  45. Note that the length always includes the terminating null character.
  46. ----------------------------------------------------------------------------*/
  47. VOID SetAppKey(LPOSTR pOct, LPBYTE lpb)
  48. {
  49. pOct->length = cbKeyApp;
  50. pOct->value = lpb;
  51. }
  52. /* C R E A T E A P P K E Y */
  53. /*----------------------------------------------------------------------------
  54. %%Function: CreateAppKey
  55. Given a guid and a userid, create the appropriate application key.
  56. The key is formated as:
  57. 0xB5 0x00 0x53 0x4C - Microsoft Object Identifier
  58. 0x01 - guid identifier
  59. <binary guid> - guid data
  60. <dword node id> - user node id
  61. ----------------------------------------------------------------------------*/
  62. VOID CreateAppKey(LPBYTE lpb, GUID * pguid, DWORD dwUserId)
  63. {
  64. CreateH221AppKeyFromGuid(lpb, pguid);
  65. CopyMemory(lpb + cbKeyApp - sizeof(DWORD), &dwUserId, sizeof(DWORD));
  66. #ifdef DEBUG
  67. TCHAR szGuid[LENGTH_SZGUID_FORMATTED];
  68. GuidToSz(pguid, szGuid);
  69. DbgMsgDc("CreateAppKey: %s %08X", szGuid, dwUserId);
  70. #endif
  71. }
  72. /* P M E M B E R F R O M D W U S E R I D */
  73. /*-------------------------------------------------------------------------
  74. %%Function: PMemberFromDwUserId
  75. -------------------------------------------------------------------------*/
  76. CNmMember * PMemberFromDwUserId(DWORD dwUserId, COBLIST *pList)
  77. {
  78. if (NULL != pList)
  79. {
  80. POSITION posCurr;
  81. POSITION pos = pList->GetHeadPosition();
  82. while (NULL != pos)
  83. {
  84. posCurr = pos;
  85. CNmMember * pMember = (CNmMember *) pList->GetNext(pos);
  86. if (dwUserId == pMember->GetGCCID())
  87. {
  88. pMember->AddRef();
  89. return pMember;
  90. }
  91. }
  92. }
  93. return NULL;
  94. }
  95. /* A D D N O D E */
  96. /*-------------------------------------------------------------------------
  97. %%Function: AddNode
  98. Add a node to a list.
  99. Initializes the ObList, if necessary.
  100. Returns the position in the list or NULL if there was a problem.
  101. -------------------------------------------------------------------------*/
  102. POSITION AddNode(PVOID pv, COBLIST ** ppList)
  103. {
  104. ASSERT(NULL != ppList);
  105. if (NULL == *ppList)
  106. {
  107. *ppList = new COBLIST();
  108. if (NULL == *ppList)
  109. return NULL;
  110. }
  111. return (*ppList)->AddTail(pv);
  112. }
  113. /* R E M O V E N O D E */
  114. /*-------------------------------------------------------------------------
  115. %%Function: RemoveNode
  116. Remove a node from a list.
  117. Sets pPos to NULL
  118. -------------------------------------------------------------------------*/
  119. PVOID RemoveNodePos(POSITION * pPos, COBLIST *pList)
  120. {
  121. if ((NULL == pList) || (NULL == pPos))
  122. return NULL;
  123. PVOID pv = pList->RemoveAt(*pPos);
  124. *pPos = NULL;
  125. return pv;
  126. }
  127. /* R E M O V E N O D E */
  128. /*-------------------------------------------------------------------------
  129. %%Function: RemoveNode
  130. -------------------------------------------------------------------------*/
  131. VOID RemoveNode(PVOID pv, COBLIST * pList)
  132. {
  133. ASSERT(NULL != pv);
  134. if (NULL != pList)
  135. {
  136. POSITION pos = pList->GetPosition(pv);
  137. RemoveNodePos(&pos, pList);
  138. }
  139. }
  140. VOID CNmChannelData::InitCT120Channel(DWORD dwUserId)
  141. {
  142. m_dwUserId = dwUserId;
  143. m_gcc_conference_id = 0;
  144. m_gcc_pIAppSap = NULL;
  145. m_mcs_channel_id = 0;
  146. m_pmcs_sap = NULL;
  147. m_gcc_node_id = 0;
  148. m_scs = SCS_UNINITIALIZED;
  149. m_pGuid = PGuid();
  150. ASSERT((NULL != m_pGuid) && (GUID_NULL != *m_pGuid));
  151. CreateAppKey(m_keyApp, m_pGuid, 0);
  152. CreateAppKey(m_keyChannel, m_pGuid, dwUserId);
  153. // initialize other gcc & mcs stuff
  154. GCCObjectKey FAR * pObjKey;
  155. ClearStruct(&m_gcc_session_key);
  156. pObjKey = &(m_gcc_session_key.application_protocol_key);
  157. pObjKey->key_type = GCC_H221_NONSTANDARD_KEY;
  158. SetAppKey(&(pObjKey->h221_non_standard_id), m_keyApp);
  159. ASSERT(0 == m_gcc_session_key.session_id);
  160. ClearStruct(&m_gcc_registry_item);
  161. ClearStruct(&m_gcc_registry_key);
  162. CopyStruct(&m_gcc_registry_key.session_key, &m_gcc_session_key);
  163. SetAppKey(&m_gcc_registry_key.resource_id, m_keyApp);
  164. ClearStruct(&m_registry_item_Private);
  165. ClearStruct(&m_registry_key_Private);
  166. CopyStruct(&m_registry_key_Private.session_key, &m_gcc_session_key);
  167. SetAppKey(&m_registry_key_Private.resource_id, m_keyChannel);
  168. UpdateScState(SCS_UNINITIALIZED, 0);
  169. }
  170. /* C L O S E C H A N N E L */
  171. /*----------------------------------------------------------------------------
  172. %%Function: CloseChannel
  173. Close the channel.
  174. Note there are no confirm messages expected for any of the GCC/MCS calls.
  175. ----------------------------------------------------------------------------*/
  176. VOID CNmChannelData::CloseChannel(void)
  177. {
  178. GCCError gccError = GCC_NO_ERROR;
  179. MCSError mcsError = MCS_NO_ERROR;
  180. if (SCS_UNINITIALIZED == m_scs)
  181. {
  182. WARNING_OUT(("in CT120Channel::CloseChannel, m_scs is SCS_UNINITIALIZED, is this OK?"));
  183. return;
  184. }
  185. DbgMsgDc("CT120Channel::CloseChannel %08X (userHandle=%p)", m_mcs_channel_id, m_pmcs_sap);
  186. m_scs = SCS_TERMINATING;
  187. if (0 != m_mcs_channel_id)
  188. {
  189. ASSERT (m_pmcs_sap);
  190. mcsError = m_pmcs_sap->ChannelLeave(m_mcs_channel_id);
  191. DbgMsgDc("CT120Channel::CloseChannel: ChannelLeave %s", GetMcsErrorString(mcsError));
  192. m_mcs_channel_id = 0;
  193. }
  194. if (NULL != m_pmcs_sap)
  195. {
  196. mcsError = m_pmcs_sap->ReleaseInterface();
  197. DbgMsgDc("CT120Channel::CloseChannel: MCS ReleaseInterface %s", GetMcsErrorString(mcsError));
  198. m_pmcs_sap = NULL;
  199. }
  200. if (NULL != m_gcc_pIAppSap)
  201. {
  202. m_gcc_pIAppSap->RegistryDeleteEntry(m_gcc_conference_id, &m_registry_key_Private);
  203. // ignore the above result
  204. m_gcc_pIAppSap->ReleaseInterface();
  205. DbgMsgDc("CT120Channel::CloseChannel: GCCDeleteSap %s", GetGccErrorString(gccError));
  206. m_gcc_pIAppSap = NULL;
  207. }
  208. m_scs = SCS_UNINITIALIZED;
  209. m_gcc_conference_id = 0;
  210. // make sure no one is around
  211. UpdateRoster(NULL, 0, FALSE, TRUE /* fRemove */);;
  212. }
  213. /* U P D A T E S C S T A T E */
  214. /*----------------------------------------------------------------------------
  215. %%Function: UpdateScState
  216. The system progresses from one state to another
  217. by making an GCC (or MCS) call that is guarenteed to
  218. produce a notification that calls this function.
  219. The calling process is released by UnBlockThread.
  220. ----------------------------------------------------------------------------*/
  221. VOID CNmChannelData::UpdateScState(SCSTATE scs, DWORD dwErr)
  222. {
  223. DBGENTRY(CNmChannelData::UpdateScState)
  224. if (m_scs != scs)
  225. {
  226. WARNING_OUT(("UpdateScState - invalid state transition (%d - %d)", m_scs, scs));
  227. dwErr = INVALID_T120_ERROR; // We should never get here
  228. }
  229. if (0 == dwErr)
  230. {
  231. switch (m_scs)
  232. {
  233. case SCS_UNINITIALIZED:
  234. dwErr = DoCreateSap();
  235. break;
  236. case SCS_CREATESAP:
  237. dwErr = DoAttach();
  238. break;
  239. case SCS_ATTACH:
  240. dwErr = DoEnroll();
  241. break;
  242. case SCS_ENROLL:
  243. dwErr = DoJoinPrivate();
  244. break;
  245. case SCS_JOIN_PRIVATE:
  246. dwErr = DoRegRetrieve();
  247. break;
  248. case SCS_REGRETRIEVE_NEW:
  249. dwErr = DoJoinNew();
  250. break;
  251. case SCS_REGRETRIEVE_EXISTS:
  252. dwErr = DoJoinOld();
  253. break;
  254. case SCS_JOIN_NEW:
  255. dwErr = DoRegChannel();
  256. break;
  257. case SCS_REGCHANNEL:
  258. case SCS_JOIN_OLD:
  259. dwErr = DoRegPrivate();
  260. break;
  261. case SCS_REGPRIVATE:
  262. DbgMsgDc(">>>>>>>>>>>UpdateScState: Complete");
  263. m_scs = SCS_CONNECTED;
  264. NotifyChannelConnected();
  265. break;
  266. case SCS_CONNECTED:
  267. case SCS_REGRETRIEVE:
  268. // we should never be called when we're in these states
  269. // so, treat it as an error and fall thru to the default case
  270. default:
  271. dwErr = INVALID_T120_ERROR; // We should never get here
  272. break;
  273. }
  274. }
  275. DbgMsgDc("UpdateScState: New state (%d) channelId=%04X", m_scs, GetMcsChannelId());
  276. if (0 != dwErr)
  277. {
  278. WARNING_OUT(("UpdateScState: Err=%d", dwErr));
  279. CloseConnection();
  280. }
  281. DBGEXIT(CNmChannelData::UpdateScState)
  282. }
  283. DWORD CNmChannelData::DoCreateSap(void)
  284. {
  285. ASSERT(SCS_UNINITIALIZED == m_scs);
  286. m_scs = SCS_CREATESAP;
  287. GCCError gccError = PFNT120::CreateAppSap(&m_gcc_pIAppSap, this, NmGccMsgHandler);
  288. DbgMsgDc("GCCCreateSap err=%s", GetGccErrorString(gccError));
  289. return (DWORD) gccError;
  290. }
  291. DWORD CNmChannelData::DoAttach(void)
  292. {
  293. ASSERT(SCS_CREATESAP == m_scs);
  294. m_scs = SCS_ATTACH;
  295. MCSError mcsError = PFNT120::AttachRequest(&m_pmcs_sap,
  296. (DomainSelector) &m_gcc_conference_id,
  297. sizeof(m_gcc_conference_id),
  298. NmMcsMsgHandler,
  299. this,
  300. ATTACHMENT_DISCONNECT_IN_DATA_LOSS | ATTACHMENT_MCS_FREES_DATA_IND_BUFFER);
  301. // This generates an async MCS_ATTACH_USER_CONFIRM
  302. DbgMsgDc("MCS_AttachRequest err=%s", GetMcsErrorString(mcsError));
  303. return (DWORD) mcsError;
  304. }
  305. DWORD CNmChannelData::DoEnroll(void)
  306. {
  307. ASSERT(SCS_ATTACH == m_scs || SCS_JOIN_STATIC_CHANNEL);
  308. m_scs = SCS_ENROLL;
  309. GCCEnrollRequest er;
  310. GCCRequestTag nReqTag;
  311. if(m_pGCCER)
  312. {
  313. m_pGCCER->pSessionKey = &m_gcc_session_key;
  314. m_pGCCER->nUserID = m_mcs_sender_id;
  315. }
  316. else
  317. {
  318. // fill in enroll request structure
  319. ::ZeroMemory(&er, sizeof(er));
  320. er.pSessionKey = &m_gcc_session_key;
  321. er.fEnrollActively = TRUE;
  322. er.nUserID = m_mcs_sender_id;
  323. // er.fConductingCapabable = FALSE;
  324. er.nStartupChannelType = MCS_DYNAMIC_MULTICAST_CHANNEL;
  325. // er.cNonCollapsedCaps = 0;
  326. // er.apNonCollapsedCaps = NULL;
  327. // er.cCollapsedCaps = 0;
  328. // er.apCollapsedCaps = NULL;
  329. er.fEnroll = TRUE;
  330. }
  331. GCCError gccError = m_gcc_pIAppSap->AppEnroll(m_gcc_conference_id, m_pGCCER != NULL ? m_pGCCER : &er, &nReqTag);
  332. DbgMsgDc("GCCApplicationEnrollRequest err=%s", GetGccErrorString(gccError));
  333. if (GCC_NO_ERROR != gccError)
  334. {
  335. ERROR_OUT(("DoEnroll failed - WHY?"));
  336. }
  337. return (DWORD) gccError;
  338. }
  339. // Join the PRIVATE data channel (m_mcs_sender_id)
  340. DWORD CNmChannelData::DoJoinPrivate(void)
  341. {
  342. ASSERT(SCS_ENROLL == m_scs || SCS_ATTACH == m_scs);
  343. m_scs = SCS_JOIN_PRIVATE;
  344. MCSError mcsError = m_pmcs_sap->ChannelJoin(m_mcs_sender_id);
  345. // This generates an async MCS_CHANNEL_JOIN_CONFIRM
  346. DbgMsgDc("MCSChannelJoinRequest (private) %04X, err=%s",
  347. m_mcs_sender_id, GetMcsErrorString(mcsError));
  348. return (DWORD) mcsError;
  349. }
  350. DWORD CNmChannelData::DoRegRetrieve(void)
  351. {
  352. ASSERT(SCS_JOIN_PRIVATE == m_scs);
  353. m_scs = SCS_REGRETRIEVE;
  354. GCCError gccError = m_gcc_pIAppSap->RegistryRetrieveEntry(
  355. m_gcc_conference_id, &m_gcc_registry_key);
  356. // This generates an async GCC_RETRIEVE_ENTRY_CONFIRM
  357. DbgMsgDc("GCCRegistryRetrieveEntryRequest err=%s", GetGccErrorString(gccError));
  358. return (DWORD) gccError;
  359. }
  360. // Register the PUBLIC channel
  361. DWORD CNmChannelData::DoRegChannel(void)
  362. {
  363. ASSERT(SCS_JOIN_NEW == m_scs);
  364. m_scs = SCS_REGCHANNEL;
  365. GCCError gccError = m_gcc_pIAppSap->RegisterChannel(
  366. m_gcc_conference_id, &m_gcc_registry_key, m_mcs_channel_id);
  367. // This generates an async GCC_REGISTER_CHANNEL_CONFIRM
  368. DbgMsgDc("GCCRegisterChannelRequest err=%s", GetGccErrorString(gccError));
  369. return (DWORD) gccError;
  370. }
  371. DWORD CNmChannelData::DoJoinStatic(ChannelID staticChannel)
  372. {
  373. m_scs = SCS_JOIN_STATIC_CHANNEL;
  374. MCSError mcsError = m_pmcs_sap->ChannelJoin(staticChannel);
  375. // This generates an async MCS_CHANNEL_JOIN_CONFIRM
  376. DbgMsgDc("MCSChannelJoinRequest %04X, err=%s",
  377. staticChannel, GetMcsErrorString(mcsError));
  378. return (DWORD) mcsError;
  379. }
  380. DWORD CNmChannelData::DoJoin(SCSTATE scs)
  381. {
  382. m_scs = scs;
  383. MCSError mcsError = m_pmcs_sap->ChannelJoin(m_mcs_channel_id);
  384. // This generates an async MCS_CHANNEL_JOIN_CONFIRM
  385. DbgMsgDc("MCSChannelJoinRequest %04X, err=%s",
  386. m_mcs_channel_id, GetMcsErrorString(mcsError));
  387. return (DWORD) mcsError;
  388. }
  389. DWORD CNmChannelData::DoJoinNew(void)
  390. {
  391. ASSERT(0 == m_mcs_channel_id);
  392. ASSERT(SCS_REGRETRIEVE_NEW == m_scs);
  393. return DoJoin(SCS_JOIN_NEW);
  394. }
  395. DWORD CNmChannelData::DoJoinOld(void)
  396. {
  397. ASSERT(0 != m_mcs_channel_id);
  398. ASSERT(SCS_REGRETRIEVE_EXISTS == m_scs);
  399. return DoJoin(SCS_JOIN_OLD);
  400. }
  401. // Register the PRIVATE data channel. (m_mcs_sender_id)
  402. DWORD CNmChannelData::DoRegPrivate(void)
  403. {
  404. ASSERT(0 != m_mcs_sender_id);
  405. ASSERT((SCS_REGCHANNEL == m_scs) || (SCS_JOIN_OLD == m_scs));
  406. m_scs = SCS_REGPRIVATE;
  407. DbgMsgDc("DoRegPrivate: channelId %04X as private for %08X", m_mcs_sender_id, m_dwUserId);
  408. GCCError gccError = m_gcc_pIAppSap->RegisterChannel(
  409. m_gcc_conference_id, &m_registry_key_Private, m_mcs_sender_id);
  410. // This generates an async GCC_REGISTER_CHANNEL_CONFIRM
  411. DbgMsgDc("GCCRegisterChannelRequest err=%s", GetGccErrorString(gccError));
  412. return (DWORD) gccError;
  413. }
  414. // deal with a GCC_RETRIEVE_ENTRY_CONFIRM notification
  415. VOID CNmChannelData::ProcessEntryConfirm(GCCAppSapMsg * pMsg)
  416. {
  417. if (pMsg->RegistryConfirm.pRegKey->resource_id.length >=
  418. m_gcc_registry_key.resource_id.length
  419. &&
  420. 0 != memcmp(m_gcc_registry_key.resource_id.value,
  421. pMsg->RegistryConfirm.pRegKey->resource_id.value,
  422. m_gcc_registry_key.resource_id.length))
  423. {
  424. OnEntryConfirmRemote(pMsg);
  425. }
  426. else
  427. {
  428. OnEntryConfirmLocal(pMsg);
  429. }
  430. }
  431. // deal with a GCC_REGISTRY_HANDLE_CONFIRM notification
  432. VOID CNmChannelData::ProcessHandleConfirm(GCCAppSapMsg * pMsg)
  433. {
  434. ASSERT(NULL != pMsg);
  435. NotifySink(&pMsg->RegAllocHandleConfirm, OnAllocateHandleConfirm);
  436. }
  437. VOID CNmChannelData::OnEntryConfirmRemote(GCCAppSapMsg * pMsg)
  438. {
  439. DWORD dwUserId;
  440. ASSERT(cbKeyApp ==
  441. pMsg->RegistryConfirm.pRegKey->resource_id.length);
  442. CopyMemory(&dwUserId,
  443. pMsg->RegistryConfirm.pRegKey->resource_id.value +
  444. cbKeyApp - sizeof(DWORD), sizeof(DWORD));
  445. DbgMsgDc("GCC_RETRIEVE_ENTRY_CONFIRM: user private channelId = %04X for userId=%04X result=%s",
  446. pMsg->RegistryConfirm.pRegItem->channel_id, dwUserId,
  447. GetGccResultString(pMsg->RegistryConfirm.nResult));
  448. if (GCC_RESULT_SUCCESSFUL == pMsg->RegistryConfirm.nResult)
  449. {
  450. UpdateMemberChannelId(dwUserId,
  451. pMsg->RegistryConfirm.pRegItem->channel_id);
  452. }
  453. else
  454. {
  455. CNmMemberId * pMemberId = GetMemberId(dwUserId);
  456. if (NULL != pMemberId)
  457. {
  458. UINT cCount = pMemberId->GetCheckIdCount();
  459. if (0 == cCount)
  460. {
  461. DbgMsgDc("CT120Channel: No more ChannelId requests %08X", dwUserId);
  462. }
  463. else
  464. {
  465. cCount--;
  466. DbgMsgDc("CT120Channel: Request Count for %08X = %0d", dwUserId, cCount);
  467. pMemberId->SetCheckIdCount(cCount);
  468. // BUGBUG: T.120 should notify us when this information is available
  469. RequestChannelId(dwUserId);
  470. }
  471. }
  472. }
  473. }
  474. VOID CNmChannelData::OnEntryConfirmLocal(GCCAppSapMsg * pMsg)
  475. {
  476. DbgMsgDc("GCC_RETRIEVE_ENTRY_CONFIRM: public channelId = %04X result=%s",
  477. pMsg->RegistryConfirm.pRegItem->channel_id,
  478. GetGccResultString(pMsg->RegistryConfirm.nResult));
  479. // Processing initial request for guid channel information
  480. ASSERT(sizeof(m_gcc_registry_item) == sizeof(*(pMsg->RegistryConfirm.pRegItem)));
  481. CopyMemory(&m_gcc_registry_item, pMsg->RegistryConfirm.pRegItem,
  482. sizeof(m_gcc_registry_item));
  483. if (GCC_RESULT_SUCCESSFUL == pMsg->RegistryConfirm.nResult)
  484. {
  485. m_mcs_channel_id = m_gcc_registry_item.channel_id;
  486. ASSERT(SCS_REGRETRIEVE == m_scs);
  487. m_scs = SCS_REGRETRIEVE_EXISTS;
  488. UpdateScState(SCS_REGRETRIEVE_EXISTS, 0);
  489. }
  490. else if (GCC_RESULT_ENTRY_DOES_NOT_EXIST == pMsg->RegistryConfirm.nResult)
  491. {
  492. DbgMsgDc(" channel does not exist - proceeding to new state");
  493. ASSERT(0 == m_mcs_channel_id);
  494. ASSERT(SCS_REGRETRIEVE == m_scs);
  495. m_scs = SCS_REGRETRIEVE_NEW;
  496. UpdateScState(SCS_REGRETRIEVE_NEW, 0);
  497. }
  498. }
  499. // deal with a GCC_APP_ROSTER_REPORT_INDICATION
  500. BOOL CNmChannelData::UpdateRoster(GCCAppSapMsg * pMsg)
  501. {
  502. UINT iRoster;
  503. GCCApplicationRoster * lpAppRoster;
  504. int iRecord;
  505. GCCApplicationRecord * lpAppRecord;
  506. DWORD dwUserId;
  507. UCID rgPeerTemp[MAX_NM_PEER];
  508. int cPeer;
  509. int i;
  510. BOOL fAdd = FALSE;
  511. BOOL fRemove = FALSE;
  512. BOOL fLocal = FALSE;
  513. DbgMsgDc("CT120Channel::UpdateRoster: conf=%d, roster count=%d",
  514. pMsg->AppRosterReportInd.nConfID,
  515. pMsg->AppRosterReportInd.cRosters);
  516. ZeroMemory(rgPeerTemp, sizeof(rgPeerTemp));
  517. /* Create rgPeerTemp[], cPeer */
  518. cPeer = 0;
  519. for (iRoster = 0;
  520. iRoster < pMsg->AppRosterReportInd.cRosters;
  521. iRoster++)
  522. {
  523. lpAppRoster = pMsg->AppRosterReportInd.apAppRosters[iRoster];
  524. if (lpAppRoster->session_key.session_id != m_gcc_session_key.session_id)
  525. continue;
  526. // Must pay attention to these flags to avoid GCC weirdness
  527. if (lpAppRoster->nodes_were_added)
  528. fAdd = TRUE;
  529. if (lpAppRoster->nodes_were_removed)
  530. fRemove = TRUE;
  531. for (iRecord = 0;
  532. iRecord < lpAppRoster->number_of_records;
  533. iRecord++)
  534. {
  535. lpAppRecord = lpAppRoster->application_record_list[iRecord];
  536. TRACE_OUT(("Node=%X, Entity=%X, AppId=%X", lpAppRecord->node_id,
  537. lpAppRecord->entity_id, lpAppRecord->application_user_id));
  538. // Search for the node in the list
  539. dwUserId = lpAppRecord->node_id;
  540. //
  541. // Check for local node
  542. //
  543. fLocal |= (dwUserId == m_dwUserIdLocal);
  544. for (i = 0; i < cPeer; i++)
  545. {
  546. if (dwUserId == rgPeerTemp[i].dwUserId)
  547. break;
  548. }
  549. if (i >= cPeer)
  550. {
  551. if (cPeer >= MAX_NM_PEER)
  552. continue; // over our limit!
  553. // Add the node to our new list
  554. rgPeerTemp[cPeer++].dwUserId = dwUserId;
  555. }
  556. // Make sure we know the sender_id's
  557. if (MCS_DYNAMIC_PRIVATE_CHANNEL == lpAppRecord->startup_channel_type)
  558. {
  559. rgPeerTemp[i].sender_id_private = lpAppRecord->application_user_id;
  560. }
  561. else
  562. {
  563. rgPeerTemp[i].sender_id_public = lpAppRecord->application_user_id;
  564. }
  565. }
  566. break; // out of for (iRoster) loop
  567. }
  568. UpdateRoster(rgPeerTemp, cPeer, fAdd, fRemove);
  569. return (fAdd && fLocal);
  570. }
  571. /* H R S E N D D A T A */
  572. /*----------------------------------------------------------------------------
  573. %%Function: HrSendData
  574. Send data on a specific channel
  575. ----------------------------------------------------------------------------*/
  576. HRESULT CNmChannelData::HrSendData(ChannelID channel_id, DWORD dwUserId, LPVOID lpv, DWORD cb, DWORD dwFlags)
  577. {
  578. DbgMsgDc("CT120Channel::HrSendData: %d bytes", cb);
  579. PDUPriority priority = MEDIUM_PRIORITY;
  580. SendDataFlags allocation = APP_ALLOCATION;
  581. DataRequestType requestType = NORMAL_SEND_DATA;
  582. if(dwFlags)
  583. {
  584. if(dwFlags & TOP_PRIORITY_MASK)
  585. {
  586. priority = TOP_PRIORITY;
  587. }
  588. else if (dwFlags & HIGH_PRIORITY_MASK)
  589. {
  590. priority = HIGH_PRIORITY;
  591. }
  592. else if (dwFlags & LOW_PRIORITY_MASK)
  593. {
  594. priority = LOW_PRIORITY;
  595. }
  596. if (dwFlags & UNIFORM_SEND_DATA_MASK)
  597. {
  598. requestType = UNIFORM_SEND_DATA;
  599. }
  600. if (dwFlags & MCS_ALLOCATION_MASK)
  601. {
  602. allocation = MCS_ALLOCATION;
  603. }
  604. }
  605. if ((0 == m_mcs_channel_id) || (NULL == m_pmcs_sap) || (0 == channel_id))
  606. {
  607. WARNING_OUT(("*** Attempted to send data on invalid channel"));
  608. return E_INVALIDARG;
  609. }
  610. MCSError mcsError = m_pmcs_sap->SendData(requestType, channel_id, priority,
  611. (unsigned char *)lpv, cb, allocation);
  612. if (0 != mcsError)
  613. {
  614. TRACE_OUT(("SendData err=%s", GetMcsErrorString(mcsError)));
  615. // Usually MCS_TRANSMIT_BUFFER_FULL
  616. return E_OUTOFMEMORY;
  617. }
  618. { // Inform the app the data has been sent
  619. NMN_DATA_XFER nmnData;
  620. nmnData.pMember = NULL;
  621. nmnData.pb = (LPBYTE) lpv;
  622. nmnData.cb = cb;
  623. nmnData.dwFlags = 0;
  624. if (0 == dwUserId)
  625. {
  626. // send out notification with NULL member (BROADCAST)
  627. NotifySink(&nmnData, OnNmDataSent);
  628. }
  629. else
  630. {
  631. nmnData.pMember = (INmMember *) PMemberFromDwUserId(dwUserId, GetMemberList());
  632. if (nmnData.pMember)
  633. {
  634. NotifySink(&nmnData, OnNmDataSent);
  635. nmnData.pMember->Release();
  636. }
  637. }
  638. }
  639. TRACE_OUT(("SendData completed successfully"));
  640. return S_OK;
  641. }
  642. // Ask GCC for the private channel id.
  643. VOID CNmChannelData::RequestChannelId(DWORD dwUserId)
  644. {
  645. BYTE keyChannel[cbKeyApp];
  646. GCCRegistryKey registry_key;
  647. DbgMsgDc("Requesting channel id for %08X", dwUserId);
  648. CopyStruct(&registry_key.session_key, &m_gcc_session_key);
  649. CreateAppKey(keyChannel, m_pGuid, dwUserId);
  650. SetAppKey(&registry_key.resource_id, keyChannel);
  651. GCCError gccError = m_gcc_pIAppSap->RegistryRetrieveEntry(
  652. m_gcc_conference_id, &registry_key);
  653. // This generates an async GCC_RETRIEVE_ENTRY_CONFIRM
  654. if (0 != gccError)
  655. {
  656. WARNING_OUT(("RequestChannelId - problem with GCCRegistryRectreiveEntryRequest"));
  657. }
  658. }
  659. VOID CNmChannelData::NotifyChannelConnected(void)
  660. {
  661. DBGENTRY(CNmChannelData::NotifyChannelConnected);
  662. if (S_OK != IsActive())
  663. {
  664. CConfObject * pConference = PConference();
  665. if (NULL != pConference)
  666. {
  667. m_fActive = TRUE;
  668. TRACE_OUT(("The channel is now officially active"));
  669. // The channel is now officially active
  670. pConference->OnChannelUpdated(this);
  671. }
  672. else
  673. {
  674. WARNING_OUT(("PConference is NULL!"));
  675. }
  676. }
  677. DBGEXIT(CNmChannelData::NotifyChannelConnected);
  678. }
  679. /* N M G C C M S G H A N D L E R */
  680. /*-------------------------------------------------------------------------
  681. %%Function: NmGccMsgHandler
  682. -------------------------------------------------------------------------*/
  683. void CALLBACK NmGccMsgHandler(GCCAppSapMsg * pMsg)
  684. {
  685. TRACE_OUT(("NmGccMsgHandler: [%d]", pMsg->eMsgType));
  686. CNmChannelData * psc = (CNmChannelData *) (pMsg->pAppData);
  687. ASSERT(NULL != psc);
  688. psc->AddRef();
  689. switch (pMsg->eMsgType)
  690. {
  691. case GCC_PERMIT_TO_ENROLL_INDICATION:
  692. TRACE_OUT((" m_conference_id = %X", pMsg->AppPermissionToEnrollInd.nConfID));
  693. TRACE_OUT((" permission = %X", pMsg->AppPermissionToEnrollInd.fPermissionGranted));
  694. if ((SCS_CONNECTED == psc->m_scs) &&
  695. (0 == pMsg->AppPermissionToEnrollInd.fPermissionGranted))
  696. {
  697. psc->CloseConnection();
  698. break;
  699. }
  700. if (SCS_CREATESAP != psc->m_scs)
  701. {
  702. TRACE_OUT((" ignoring Enroll Indication"));
  703. break;
  704. }
  705. psc->m_gcc_conference_id = pMsg->AppPermissionToEnrollInd.nConfID;
  706. psc->UpdateScState(SCS_CREATESAP, !pMsg->AppPermissionToEnrollInd.fPermissionGranted);
  707. break;
  708. case GCC_ENROLL_CONFIRM:
  709. TRACE_OUT((" result = %s", GetGccResultString(pMsg->AppEnrollConfirm.nResult)));
  710. if (GCC_RESULT_SUCCESSFUL == pMsg->AppEnrollConfirm.nResult)
  711. {
  712. TRACE_OUT((" m_conference_id = %X", pMsg->AppEnrollConfirm.nConfID));
  713. TRACE_OUT((" entity_id = %X", pMsg->AppEnrollConfirm.eidMyself));
  714. TRACE_OUT((" node_id = %X", pMsg->AppEnrollConfirm.nidMyself));
  715. psc->m_gcc_node_id = pMsg->AppEnrollConfirm.nidMyself;
  716. }
  717. break;
  718. case GCC_APP_ROSTER_REPORT_INDICATION:
  719. if(psc->UpdateRoster(pMsg) && psc->m_scs == SCS_ENROLL)
  720. {
  721. psc->UpdateScState(SCS_ENROLL, GCC_RESULT_SUCCESSFUL);
  722. }
  723. break;
  724. case GCC_REGISTER_CHANNEL_CONFIRM:
  725. DbgMsgDc("GCC_REGISTER_CHANNEL_CONFIRM: channel id = %04X result = %s",
  726. pMsg->RegistryConfirm.pRegItem->channel_id,
  727. GetGccResultString(pMsg->RegistryConfirm.nResult));
  728. if (GCC_RESULT_SUCCESSFUL == pMsg->RegistryConfirm.nResult)
  729. {
  730. if (psc->GetMcsChannelId() ==
  731. pMsg->RegistryConfirm.pRegItem->channel_id)
  732. {
  733. ASSERT((0 == psc->m_gcc_registry_item.item_type) ||
  734. (GCC_REGISTRY_NONE == psc->m_gcc_registry_item.item_type));
  735. ASSERT(sizeof(psc->m_gcc_registry_item) == sizeof(*(pMsg->RegistryConfirm.pRegItem)));
  736. CopyMemory(&psc->m_gcc_registry_item, pMsg->RegistryConfirm.pRegItem,
  737. sizeof(psc->m_gcc_registry_item));
  738. }
  739. else
  740. {
  741. ASSERT(psc->SenderChannelId() ==
  742. pMsg->RegistryConfirm.pRegItem->channel_id);
  743. ASSERT(0 == psc->m_registry_item_Private.item_type);
  744. ASSERT(sizeof(psc->m_registry_item_Private) == sizeof(*(pMsg->RegistryConfirm.pRegItem)));
  745. CopyMemory(&psc->m_registry_item_Private, pMsg->RegistryConfirm.pRegItem,
  746. sizeof(psc->m_registry_item_Private));
  747. }
  748. }
  749. ASSERT((SCS_REGCHANNEL == psc->m_scs) || (SCS_REGPRIVATE == psc->m_scs));
  750. psc->UpdateScState(psc->m_scs, pMsg->RegistryConfirm.nResult);
  751. break;
  752. case GCC_RETRIEVE_ENTRY_CONFIRM:
  753. psc->ProcessEntryConfirm(pMsg);
  754. break;
  755. case GCC_ALLOCATE_HANDLE_CONFIRM:
  756. psc->ProcessHandleConfirm(pMsg);
  757. break;
  758. default:
  759. break;
  760. }
  761. psc->Release();
  762. }
  763. /* N M M C S M S G H A N D L E R */
  764. /*-------------------------------------------------------------------------
  765. %%Function: NmMcsMsgHandler
  766. -------------------------------------------------------------------------*/
  767. void CALLBACK NmMcsMsgHandler(unsigned int uMsg, LPARAM lParam, PVOID pv)
  768. {
  769. CNmChannelData * psc = (CNmChannelData *) pv;
  770. ASSERT(NULL != psc);
  771. // TRACE_OUT(("[%s]", GetMcsMsgString(uMsg)));
  772. psc->AddRef();
  773. switch (uMsg)
  774. {
  775. case MCS_ATTACH_USER_CONFIRM:
  776. {
  777. DbgMsgDc("MCS_ATTACH_USER_CONFIRM channelId=%04X result=%s",
  778. LOWORD(lParam), GetMcsResultString(HIWORD(lParam) ));
  779. if (RESULT_SUCCESSFUL == HIWORD(lParam))
  780. {
  781. DbgMsgDc(" Local m_mcs_sender_id = %04X", LOWORD(lParam));
  782. psc->m_mcs_sender_id = LOWORD(lParam);
  783. }
  784. psc->UpdateScState(SCS_ATTACH, (DWORD) HIWORD(lParam));
  785. break;
  786. }
  787. case MCS_CHANNEL_JOIN_CONFIRM:
  788. {
  789. DbgMsgDc("MCS_CHANNEL_JOIN_CONFIRM channelId=%04X result=%s",
  790. LOWORD(lParam), GetMcsResultString(HIWORD(lParam) ));
  791. if (RESULT_SUCCESSFUL == HIWORD(lParam))
  792. {
  793. if (psc->m_mcs_sender_id == LOWORD(lParam))
  794. {
  795. ASSERT(SCS_JOIN_PRIVATE == psc->m_scs);
  796. }
  797. else
  798. {
  799. ASSERT((0 == psc->m_mcs_channel_id) ||
  800. (psc->m_mcs_channel_id == LOWORD(lParam)));
  801. psc->m_mcs_channel_id = LOWORD(lParam);
  802. }
  803. }
  804. ASSERT((SCS_JOIN_NEW == psc->m_scs) ||
  805. (SCS_JOIN_OLD == psc->m_scs) ||
  806. (SCS_JOIN_PRIVATE == psc->m_scs) ||
  807. (SCS_CONNECTED == psc->m_scs)||
  808. (SCS_JOIN_STATIC_CHANNEL == psc->m_scs));
  809. psc->UpdateScState(psc->m_scs, (DWORD) HIWORD(lParam));
  810. break;
  811. }
  812. case MCS_UNIFORM_SEND_DATA_INDICATION:
  813. case MCS_SEND_DATA_INDICATION: // lParam == SendData *
  814. {
  815. SendData * pSendData = (SendData *) lParam;
  816. ASSERT(NULL != pSendData);
  817. CNmMember * pMember = psc->PMemberFromSenderId(pSendData->initiator);
  818. if (NULL != pMember)
  819. {
  820. if (uMsg == MCS_UNIFORM_SEND_DATA_INDICATION)
  821. {
  822. //
  823. // Skip UNIFORM notifications that came from us
  824. //
  825. ULONG memberID;
  826. pMember->GetID(&memberID);
  827. if (memberID == psc->m_gcc_node_id)
  828. {
  829. // We sent this, skip it.
  830. goto RelMember;
  831. }
  832. }
  833. ASSERT (pSendData->segmentation == (SEGMENTATION_BEGIN | SEGMENTATION_END));
  834. NMN_DATA_XFER nmnData;
  835. nmnData.pMember =(INmMember *) pMember;
  836. nmnData.pb = pSendData->user_data.value;
  837. nmnData.cb = pSendData->user_data.length;
  838. nmnData.dwFlags = (ULONG)
  839. (NM_DF_SEGMENT_BEGIN | NM_DF_SEGMENT_END) |
  840. ((psc->GetMcsChannelId() == pSendData->channel_id) ?
  841. NM_DF_BROADCAST : NM_DF_PRIVATE);
  842. psc->NotifySink((PVOID) &nmnData, OnNmDataReceived);
  843. RelMember:
  844. pMember->Release();
  845. }
  846. break;
  847. }
  848. default:
  849. break;
  850. }
  851. psc->Release();
  852. }
  853. //
  854. // CNmMemberId
  855. //
  856. CNmMemberId::CNmMemberId(CNmMember *pMember, UCID * pucid) :
  857. m_channelId(pucid->channelId),
  858. m_sender_id_public(pucid->sender_id_public),
  859. m_sender_id_private(pucid->sender_id_private),
  860. m_cCheckId(0),
  861. m_pMember(pMember)
  862. {
  863. }
  864. VOID CNmMemberId::UpdateRosterInfo(UCID * pucid)
  865. {
  866. if (0 == m_channelId)
  867. m_channelId = pucid->channelId;
  868. if (0 == m_sender_id_private)
  869. m_sender_id_private = pucid->sender_id_private;
  870. if (0 == m_sender_id_public)
  871. m_sender_id_public = pucid->sender_id_public;
  872. }
  873. //
  874. // CNmChannelData
  875. //
  876. CNmChannelData::CNmChannelData(CConfObject * pConference, REFGUID rguid, PGCCEnrollRequest pER) :
  877. CConnectionPointContainer(g_apiidCP, ARRAY_ELEMENTS(g_apiidCP)),
  878. m_pConference(pConference),
  879. m_fClosed(TRUE),
  880. m_fActive(FALSE),
  881. m_cMember(0),
  882. m_pListMemberId(NULL),
  883. m_pListMember(NULL),
  884. m_pGCCER(pER)
  885. {
  886. m_guid = rguid;
  887. ASSERT(GUID_NULL != rguid);
  888. m_dwUserIdLocal = pConference->GetDwUserIdLocal();
  889. ASSERT(INVALID_GCCID != m_dwUserIdLocal);
  890. DbgMsg(iZONE_OBJECTS, "Obj: %08X created CNmChannelData", this);
  891. }
  892. CNmChannelData::~CNmChannelData(void)
  893. {
  894. DBGENTRY(CNmChannelData::~CNmChannelData);
  895. // This will keep us from being deleted again...
  896. ++m_ulcRef;
  897. CloseConnection();
  898. FreeMemberIdList(&m_pListMemberId);
  899. delete m_pListMember;
  900. if(m_pConference)
  901. {
  902. m_pConference->RemoveDataChannelGUID(m_guid);
  903. }
  904. DbgMsg(iZONE_OBJECTS, "Obj: %08X destroyed CNmChannelData", this);
  905. DBGEXIT(CNmChannelData::~CNmChannelData);
  906. }
  907. /* A D D M E M B E R */
  908. /*-------------------------------------------------------------------------
  909. %%Function: AddMember
  910. -------------------------------------------------------------------------*/
  911. VOID CNmChannelData::AddMember(CNmMember * pMember)
  912. {
  913. DbgMsgDc("CNmChannelData::AddMember [%ls] id=%08X",
  914. pMember->GetName(), pMember->GetGCCID());
  915. m_cMember++;
  916. pMember->AddRef();
  917. AddNode(pMember, &m_pListMember);
  918. INmMember * pNmMember = (INmMember *) pMember;
  919. NotifySink(pNmMember, OnNotifyChannelMemberAdded);
  920. }
  921. /* R E M O V E M E M B E R */
  922. /*-------------------------------------------------------------------------
  923. %%Function: RemoveMember
  924. -------------------------------------------------------------------------*/
  925. VOID CNmChannelData::RemoveMember(CNmMember * pMember)
  926. {
  927. DbgMsgDc("CNmChannelData::RemoveMember [%ls] id=%08X",
  928. pMember->GetName(), pMember->GetGCCID());
  929. m_cMember--;
  930. ASSERT((int)m_cMember >= 0);
  931. RemoveNode(pMember, m_pListMember);
  932. INmMember * pNmMember = (INmMember *) pMember;
  933. NotifySink(pNmMember, OnNotifyChannelMemberRemoved);
  934. pMember->Release(); // Release AFTER notifying everyone
  935. }
  936. /* O P E N C O N N E C T I O N */
  937. /*-------------------------------------------------------------------------
  938. %%Function: OpenConnection
  939. Open a T.120 data connection (init both public and private channels)
  940. -------------------------------------------------------------------------*/
  941. HRESULT CNmChannelData::OpenConnection(void)
  942. {
  943. TRACE_OUT(("CNmChannelData::OpenConection()"));
  944. if (!m_fClosed)
  945. return E_FAIL; // already open
  946. m_fClosed = FALSE; // need to call CloseConnection after this
  947. if (FAILED(PFNT120::Init()))
  948. return E_FAIL;
  949. InitCT120Channel(m_dwUserIdLocal);
  950. return S_OK;
  951. }
  952. /* C L O S E C O N N E C T I O N */
  953. /*-------------------------------------------------------------------------
  954. %%Function: CloseConnection
  955. Close the data channel - this matches what is done in OpenConnection
  956. -------------------------------------------------------------------------*/
  957. HRESULT CNmChannelData::CloseConnection(void)
  958. {
  959. DBGENTRY(CNmChannelData::CloseConnection);
  960. HRESULT hr = S_OK;
  961. if (!m_fClosed)
  962. {
  963. m_fClosed = TRUE;
  964. // Close any open T.120 channels
  965. CloseChannel();
  966. if (0 != m_cMember)
  967. {
  968. // force roster update with no peers
  969. DbgMsgDc("CloseConnection: %d members left", m_cMember);
  970. UpdateRoster(NULL, 0, FALSE, TRUE /* fRemove */);
  971. ASSERT(IsEmpty());
  972. }
  973. CConfObject * pConference = PConference();
  974. if (NULL != pConference)
  975. {
  976. m_fActive = FALSE;
  977. // The channel is now officially inactive
  978. pConference->OnChannelUpdated(this);
  979. }
  980. }
  981. DBGEXIT_HR(CNmChannelData::CloseConnection, hr);
  982. return hr;
  983. }
  984. /* U P D A T E P E E R */
  985. /*-------------------------------------------------------------------------
  986. %%Function: UpdatePeer
  987. -------------------------------------------------------------------------*/
  988. VOID CNmChannelData::UpdatePeer(CNmMember * pMember, UCID *pucid, BOOL fAdd)
  989. {
  990. #ifdef DEBUG
  991. DbgMsgDc("UpdatePeer (%08X) fAdd=%d fLocal=%d", pMember, fAdd, pMember->FLocal());
  992. if (NULL != pucid)
  993. {
  994. DbgMsgDc(" channelId=(%04X) dwUserId=%08X", pucid->channelId, pucid->dwUserId);
  995. }
  996. #endif /* DEBUG */
  997. if (fAdd)
  998. {
  999. CNmMemberId *pMemberId = new CNmMemberId(pMember, pucid);
  1000. if (NULL != pMemberId)
  1001. {
  1002. AddNode(pMemberId, &m_pListMemberId);
  1003. AddMember(pMember);
  1004. }
  1005. }
  1006. else
  1007. {
  1008. CNmMemberId *pMemberId = GetMemberId(pMember);
  1009. if (NULL != pMemberId)
  1010. {
  1011. RemoveNode(pMemberId, m_pListMemberId);
  1012. delete pMemberId;
  1013. RemoveMember(pMember);
  1014. }
  1015. }
  1016. }
  1017. /* U P D A T E R O S T E R */
  1018. /*-------------------------------------------------------------------------
  1019. %%Function: UpdateRoster
  1020. Update the local peer list based on the new roster data
  1021. -------------------------------------------------------------------------*/
  1022. VOID CNmChannelData::UpdateRoster(UCID * rgPeer, int cPeer, BOOL fAdd, BOOL fRemove)
  1023. {
  1024. int iPeer;
  1025. DWORD dwUserId;
  1026. CNmMember * pMember;
  1027. COBLIST * pList;
  1028. DbgMsgDc("CNmChannelData::UpdateRoster: %d peers, fAdd=%d, fRemove=%d",
  1029. cPeer, fAdd, fRemove);
  1030. if (NULL != m_pListMemberId)
  1031. {
  1032. for (POSITION pos = m_pListMemberId->GetHeadPosition(); NULL != pos; )
  1033. {
  1034. BOOL fFound = FALSE;
  1035. CNmMemberId *pMemberId = (CNmMemberId *) m_pListMemberId->GetNext(pos);
  1036. ASSERT(NULL != pMemberId);
  1037. pMember = pMemberId->GetMember();
  1038. ASSERT(NULL != pMember);
  1039. dwUserId = pMember->GetGCCID();
  1040. if (0 != dwUserId)
  1041. {
  1042. for (iPeer = 0; iPeer < cPeer; iPeer++)
  1043. {
  1044. if (dwUserId == rgPeer[iPeer].dwUserId)
  1045. {
  1046. fFound = TRUE;
  1047. // remove from the new list
  1048. // so that the peer will not be added below
  1049. rgPeer[iPeer].dwUserId = 0;
  1050. // no change, but make sure we know sender_ids
  1051. pMemberId->UpdateRosterInfo(&rgPeer[iPeer]);
  1052. // try to find channel id, if necessary
  1053. if ((0 == pMemberId->GetChannelId()) &&
  1054. (0 == pMemberId->GetCheckIdCount())
  1055. && !pMember->FLocal())
  1056. {
  1057. pMemberId->SetCheckIdCount(MAX_CHECKID_COUNT);
  1058. RequestChannelId(dwUserId);
  1059. }
  1060. break;
  1061. }
  1062. }
  1063. }
  1064. if (!fFound && fRemove)
  1065. {
  1066. pMember->AddRef();
  1067. // Unable to find old peer in new list - delete it
  1068. UpdatePeer(pMember, NULL, FALSE /* fAdd */ );
  1069. pMember->Release();
  1070. }
  1071. }
  1072. }
  1073. if (!fAdd)
  1074. return;
  1075. // Use the conference list to find member data
  1076. pList = PConference()->GetMemberList();
  1077. /* Add new peers */
  1078. for (iPeer = 0; iPeer < cPeer; iPeer++)
  1079. {
  1080. dwUserId = rgPeer[iPeer].dwUserId;
  1081. if (0 == dwUserId)
  1082. continue;
  1083. // PMemberFromDwUserId returns AddRef'd member
  1084. pMember = PMemberFromDwUserId(dwUserId, pList);
  1085. if (NULL == pMember)
  1086. {
  1087. WARNING_OUT(("UpdateRoster: Member not found! dwUserId=%08X", dwUserId));
  1088. }
  1089. else
  1090. {
  1091. UpdatePeer(pMember, &rgPeer[iPeer], TRUE /* fAdd */);
  1092. pMember->Release();
  1093. }
  1094. }
  1095. }
  1096. /* U P D A T E M E M B E R C H A N N E L I D */
  1097. /*-------------------------------------------------------------------------
  1098. %%Function: UpdateMemberChannelId
  1099. -------------------------------------------------------------------------*/
  1100. VOID CNmChannelData::UpdateMemberChannelId(DWORD dwUserId, ChannelID channelId)
  1101. {
  1102. // PMemberFromDwUserId returns AddRef'd member
  1103. CNmMember * pMember = PMemberFromDwUserId(dwUserId, PConference()->GetMemberList());
  1104. TRACE_OUT(("Member (%08X) private channelId=(%04X)", pMember, channelId));
  1105. if (NULL != pMember)
  1106. {
  1107. UCID ucid;
  1108. ClearStruct(&ucid);
  1109. ucid.channelId = channelId;
  1110. UpdateRosterInfo(pMember, &ucid);
  1111. pMember->Release();
  1112. }
  1113. }
  1114. /* G E T M E M B E R I D */
  1115. /*-------------------------------------------------------------------------
  1116. %%Function: GetMemberId
  1117. -------------------------------------------------------------------------*/
  1118. CNmMemberId * CNmChannelData::GetMemberId(CNmMember *pMember)
  1119. {
  1120. if (NULL != m_pListMemberId)
  1121. {
  1122. POSITION pos = m_pListMemberId->GetHeadPosition();
  1123. while (NULL != pos)
  1124. {
  1125. CNmMemberId *pMemberId = (CNmMemberId *) m_pListMemberId->GetNext(pos);
  1126. ASSERT(NULL != pMemberId);
  1127. if (pMemberId->GetMember() == pMember)
  1128. {
  1129. return pMemberId;
  1130. }
  1131. }
  1132. }
  1133. return NULL;
  1134. }
  1135. /* G E T M E M B E R I D */
  1136. /*-------------------------------------------------------------------------
  1137. %%Function: GetMemberId
  1138. -------------------------------------------------------------------------*/
  1139. CNmMemberId * CNmChannelData::GetMemberId(DWORD dwUserId)
  1140. {
  1141. if (NULL != m_pListMemberId)
  1142. {
  1143. POSITION pos = m_pListMemberId->GetHeadPosition();
  1144. while (NULL != pos)
  1145. {
  1146. CNmMemberId *pMemberId = (CNmMemberId *) m_pListMemberId->GetNext(pos);
  1147. ASSERT(NULL != pMemberId);
  1148. CNmMember *pMember = pMemberId->GetMember();
  1149. ASSERT(NULL != pMember);
  1150. if (pMember->GetGCCID() == dwUserId)
  1151. {
  1152. return pMemberId;
  1153. }
  1154. }
  1155. }
  1156. return NULL;
  1157. }
  1158. /* U P D A T E R O S T E R I N F O */
  1159. /*-------------------------------------------------------------------------
  1160. %%Function: UpdateRosterInfo
  1161. -------------------------------------------------------------------------*/
  1162. VOID CNmChannelData::UpdateRosterInfo(CNmMember *pMember, UCID * pucid)
  1163. {
  1164. CNmMemberId *pMemberId = GetMemberId(pMember);
  1165. if (NULL != pMemberId)
  1166. {
  1167. pMemberId->UpdateRosterInfo(pucid);
  1168. }
  1169. }
  1170. /* G E T C H A N N E L I D */
  1171. /*-------------------------------------------------------------------------
  1172. %%Function: GetChannelId
  1173. -------------------------------------------------------------------------*/
  1174. ChannelID CNmChannelData::GetChannelId(CNmMember *pMember)
  1175. {
  1176. CNmMemberId *pMemberId = GetMemberId(pMember);
  1177. if (NULL != pMemberId)
  1178. {
  1179. return pMemberId->GetChannelId();
  1180. }
  1181. return 0;
  1182. }
  1183. /* P M E M B E R F R O M S E N D E R I D */
  1184. /*-------------------------------------------------------------------------
  1185. %%Function: PMemberFromSenderId
  1186. -------------------------------------------------------------------------*/
  1187. CNmMember * CNmChannelData::PMemberFromSenderId(UserID id)
  1188. {
  1189. if (NULL != m_pListMemberId)
  1190. {
  1191. POSITION pos = m_pListMemberId->GetHeadPosition();
  1192. while (NULL != pos)
  1193. {
  1194. CNmMemberId * pMemberId = (CNmMemberId *) m_pListMemberId->GetNext(pos);
  1195. ASSERT(NULL != pMemberId);
  1196. if (pMemberId->FSenderId(id))
  1197. {
  1198. CNmMember* pMember = pMemberId->GetMember();
  1199. ASSERT(NULL != pMember);
  1200. pMember->AddRef();
  1201. return pMember;
  1202. }
  1203. }
  1204. }
  1205. return NULL;
  1206. }
  1207. ///////////////////////////
  1208. // CNmChannelData:IUknown
  1209. ULONG STDMETHODCALLTYPE CNmChannelData::AddRef(void)
  1210. {
  1211. TRACE_OUT(("CNmChannelData::AddRef this = 0x%X", this));
  1212. return RefCount::AddRef();
  1213. }
  1214. ULONG STDMETHODCALLTYPE CNmChannelData::Release(void)
  1215. {
  1216. TRACE_OUT(("CNmChannelData::Release this = 0x%X", this));
  1217. return RefCount::Release();
  1218. }
  1219. HRESULT STDMETHODCALLTYPE CNmChannelData::QueryInterface(REFIID riid, PVOID *ppv)
  1220. {
  1221. HRESULT hr = S_OK;
  1222. if ((riid == IID_IUnknown) || (riid == IID_INmChannelData2) || (riid == IID_INmChannelData) || (riid == IID_INmChannel))
  1223. {
  1224. *ppv = (INmChannelData2 *)this;
  1225. TRACE_OUT(("CNmChannel::QueryInterface(): Returning INmChannelData."));
  1226. }
  1227. else if (riid == IID_IConnectionPointContainer)
  1228. {
  1229. *ppv = (IConnectionPointContainer *) this;
  1230. TRACE_OUT(("CNmChannel::QueryInterface(): Returning IConnectionPointContainer."));
  1231. }
  1232. else
  1233. {
  1234. hr = E_NOINTERFACE;
  1235. *ppv = NULL;
  1236. TRACE_OUT(("CNmChannel::QueryInterface(): Called on unknown interface."));
  1237. }
  1238. if (S_OK == hr)
  1239. {
  1240. AddRef();
  1241. }
  1242. return hr;
  1243. }
  1244. ///////////////////////
  1245. // INmChannelData
  1246. HRESULT STDMETHODCALLTYPE CNmChannelData::GetGuid(GUID *pGuid)
  1247. {
  1248. if (NULL == pGuid)
  1249. return E_POINTER;
  1250. *pGuid = m_guid;
  1251. return S_OK;
  1252. }
  1253. HRESULT STDMETHODCALLTYPE CNmChannelData::SendData(INmMember *pMember, ULONG cb, LPBYTE pv, ULONG uOptions)
  1254. {
  1255. HRESULT hr = S_OK;
  1256. if (!m_fActive)
  1257. {
  1258. // No active Channels, yet
  1259. return E_FAIL;
  1260. }
  1261. if ((NULL == pv) || (0 == cb))
  1262. {
  1263. return S_FALSE;
  1264. }
  1265. if (IsBadReadPtr(pv, cb))
  1266. {
  1267. return E_POINTER;
  1268. }
  1269. CNmMember * pDest = (CNmMember *) pMember;
  1270. COBLIST * pList = GetMemberList();
  1271. if (NULL == pMember)
  1272. {
  1273. hr = HrSendData(GetMcsChannelId(), 0, pv, cb, uOptions);
  1274. }
  1275. else if ((NULL == pList) || (NULL == pList->Lookup(pDest)) )
  1276. {
  1277. // Destination is not in list
  1278. hr = E_INVALIDARG;
  1279. }
  1280. else
  1281. {
  1282. ChannelID channel_id = GetChannelId(pDest);
  1283. if (0 == channel_id)
  1284. {
  1285. WARNING_OUT(("Unable to find user destination channel?"));
  1286. CNmMemberId *pMemberId = GetMemberId(pDest);
  1287. if (NULL == pMemberId)
  1288. {
  1289. hr = E_UNEXPECTED;
  1290. }
  1291. else
  1292. {
  1293. channel_id = pMemberId->SenderId();
  1294. hr = (0 == channel_id) ? E_FAIL : S_OK;
  1295. }
  1296. }
  1297. if (SUCCEEDED(hr))
  1298. {
  1299. hr = HrSendData(channel_id, pDest->GetGCCID(), pv, cb, uOptions);
  1300. }
  1301. }
  1302. return hr;
  1303. }
  1304. HRESULT STDMETHODCALLTYPE CNmChannelData::RegistryAllocateHandle(ULONG numberOfHandlesRequested)
  1305. {
  1306. if (!m_fActive)
  1307. {
  1308. // No active Channels, yet
  1309. return E_FAIL;
  1310. }
  1311. if(numberOfHandlesRequested == 0)
  1312. {
  1313. return E_INVALIDARG;
  1314. }
  1315. //
  1316. // Request handles from gcc
  1317. //
  1318. GCCError gccError = m_gcc_pIAppSap->RegistryAllocateHandle(m_gcc_conference_id, numberOfHandlesRequested);
  1319. if(gccError == GCC_NO_ERROR)
  1320. {
  1321. return S_OK;
  1322. }
  1323. else
  1324. {
  1325. return E_FAIL;
  1326. }
  1327. }
  1328. ///////////////
  1329. // INmChannel
  1330. HRESULT STDMETHODCALLTYPE CNmChannelData::IsSameAs(INmChannel *pChannel)
  1331. {
  1332. HRESULT hr;
  1333. PVOID pv;
  1334. if (pChannel == NULL)
  1335. {
  1336. hr = E_INVALIDARG;
  1337. }
  1338. else
  1339. {
  1340. hr = pChannel->QueryInterface(IID_INmChannelData, &pv);
  1341. if (SUCCEEDED(hr))
  1342. {
  1343. hr = (this == (PVOID) ((CNmChannelData *)(INmChannelData *)pv)) ? S_OK : S_FALSE;
  1344. ((IUnknown *) pv)->Release();
  1345. }
  1346. }
  1347. return hr;
  1348. }
  1349. HRESULT STDMETHODCALLTYPE CNmChannelData::IsActive(void)
  1350. {
  1351. return m_fActive ? S_OK : S_FALSE;
  1352. }
  1353. HRESULT STDMETHODCALLTYPE CNmChannelData::SetActive(BOOL fActive)
  1354. {
  1355. TRACE_OUT(("CNmChannelData::SetActive(%d)", fActive));
  1356. NM_CONFERENCE_STATE state;
  1357. // Must be in a non-idle conference
  1358. CConfObject * pConference = PConference();
  1359. pConference->GetState(&state);
  1360. if ((NULL == pConference) || state == NM_CONFERENCE_IDLE)
  1361. return E_FAIL;
  1362. if (fActive)
  1363. {
  1364. if (S_OK == IsActive())
  1365. return S_OK;
  1366. return OpenConnection();
  1367. }
  1368. else
  1369. {
  1370. if (S_FALSE == IsActive())
  1371. return S_OK;
  1372. return CloseConnection();
  1373. }
  1374. }
  1375. HRESULT STDMETHODCALLTYPE CNmChannelData::GetConference(INmConference **ppConference)
  1376. {
  1377. return ::GetConference(ppConference);
  1378. }
  1379. HRESULT STDMETHODCALLTYPE CNmChannelData::GetInterface(IID *piid)
  1380. {
  1381. HRESULT hr = E_POINTER;
  1382. if (NULL != piid)
  1383. {
  1384. *piid = IID_INmChannelData;
  1385. hr = S_OK;
  1386. }
  1387. return hr;
  1388. }
  1389. HRESULT STDMETHODCALLTYPE CNmChannelData::GetNmch(ULONG *puch)
  1390. {
  1391. HRESULT hr = E_POINTER;
  1392. if (NULL != puch)
  1393. {
  1394. *puch = NMCH_DATA;
  1395. hr = S_OK;
  1396. }
  1397. return hr;
  1398. }
  1399. HRESULT STDMETHODCALLTYPE CNmChannelData::EnumMember(IEnumNmMember **ppEnum)
  1400. {
  1401. HRESULT hr = E_POINTER;
  1402. if (NULL != ppEnum)
  1403. {
  1404. *ppEnum = new CEnumNmMember( GetMemberList(), m_cMember);
  1405. hr = (NULL != *ppEnum)? S_OK : E_OUTOFMEMORY;
  1406. }
  1407. return hr;
  1408. }
  1409. HRESULT STDMETHODCALLTYPE CNmChannelData::GetMemberCount(ULONG *puCount)
  1410. {
  1411. HRESULT hr = E_POINTER;
  1412. if (NULL != puCount)
  1413. {
  1414. *puCount = m_cMember;
  1415. hr = S_OK;
  1416. }
  1417. return hr;
  1418. }
  1419. ///////////////////////////////////////////////////////////////////////////
  1420. // Utility Functions
  1421. HRESULT OnNmDataSent(IUnknown *pChannelDataNotify, void *pv, REFIID riid)
  1422. {
  1423. NMN_DATA_XFER * pData = (NMN_DATA_XFER *) pv;
  1424. if (IID_INmChannelDataNotify.Data1 == riid.Data1 || IID_INmChannelDataNotify2.Data1 == riid.Data1)
  1425. {
  1426. ((INmChannelDataNotify2*)pChannelDataNotify)->DataSent(
  1427. pData->pMember, pData->cb, pData->pb);
  1428. }
  1429. return S_OK;
  1430. }
  1431. HRESULT OnNmDataReceived(IUnknown *pChannelDataNotify, void *pv, REFIID riid)
  1432. {
  1433. NMN_DATA_XFER * pData = (NMN_DATA_XFER *) pv;
  1434. if (IID_INmChannelDataNotify.Data1 == riid.Data1 || IID_INmChannelDataNotify2.Data1 == riid.Data1)
  1435. {
  1436. ((INmChannelDataNotify2*)pChannelDataNotify)->DataReceived(
  1437. pData->pMember, pData->cb, pData->pb, pData->dwFlags);
  1438. }
  1439. return S_OK;
  1440. }
  1441. HRESULT OnAllocateHandleConfirm(IUnknown *pChannelDataNotify, void *pv, REFIID riid)
  1442. {
  1443. if(IID_INmChannelDataNotify2.Data1 == riid.Data1)
  1444. {
  1445. GCCRegAllocateHandleConfirm *pConfirm = (GCCRegAllocateHandleConfirm *)pv;
  1446. ((INmChannelDataNotify2*)pChannelDataNotify)->AllocateHandleConfirm(pConfirm->nFirstHandle,
  1447. pConfirm->cHandles);
  1448. }
  1449. return S_OK;
  1450. }
  1451. ///////////////////////////////////////////////////////////////////////////
  1452. // Utility Functions
  1453. /* F R E E M E M B E R ID L I S T */
  1454. /*-------------------------------------------------------------------------
  1455. %%Function: FreeMemberIdList
  1456. -------------------------------------------------------------------------*/
  1457. VOID FreeMemberIdList(COBLIST ** ppList)
  1458. {
  1459. DBGENTRY(FreeMemberIdList);
  1460. ASSERT(NULL != ppList);
  1461. if (NULL != *ppList)
  1462. {
  1463. while (!(*ppList)->IsEmpty())
  1464. {
  1465. CNmMemberId * pMemberId = (CNmMemberId *) (*ppList)->RemoveHead();
  1466. delete pMemberId;
  1467. }
  1468. delete *ppList;
  1469. *ppList = NULL;
  1470. }
  1471. }
  1472. ///////////////////////////////////////////////////////////////////////////
  1473. //
  1474. // GCC / MCS Errors
  1475. #ifdef DEBUG
  1476. LPCTSTR _FormatSzErr(LPTSTR psz, UINT uErr)
  1477. {
  1478. static char szErr[MAX_PATH];
  1479. wsprintf(szErr, "%s 0x%08X (%d)", psz, uErr, uErr);
  1480. return szErr;
  1481. }
  1482. #define STRING_CASE(val) case val: pcsz = #val; break
  1483. LPCTSTR GetGccErrorString(GCCError uErr)
  1484. {
  1485. LPCTSTR pcsz;
  1486. switch (uErr)
  1487. {
  1488. STRING_CASE(GCC_NO_ERROR);
  1489. STRING_CASE(GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  1490. STRING_CASE(GCC_NOT_INITIALIZED);
  1491. STRING_CASE(GCC_ALREADY_INITIALIZED);
  1492. STRING_CASE(GCC_ALLOCATION_FAILURE);
  1493. STRING_CASE(GCC_NO_SUCH_APPLICATION);
  1494. STRING_CASE(GCC_INVALID_CONFERENCE);
  1495. default:
  1496. pcsz = _FormatSzErr("GccError", uErr);
  1497. break;
  1498. }
  1499. return pcsz;
  1500. }
  1501. LPCTSTR GetMcsErrorString(MCSError uErr)
  1502. {
  1503. LPCTSTR pcsz;
  1504. switch (uErr)
  1505. {
  1506. STRING_CASE(MCS_NO_ERROR);
  1507. STRING_CASE(MCS_USER_NOT_ATTACHED);
  1508. STRING_CASE(MCS_NO_SUCH_USER);
  1509. STRING_CASE(MCS_TRANSMIT_BUFFER_FULL);
  1510. STRING_CASE(MCS_NO_SUCH_CONNECTION);
  1511. default:
  1512. pcsz = _FormatSzErr("McsError", uErr);
  1513. break;
  1514. }
  1515. return pcsz;
  1516. }
  1517. LPCTSTR GetGccResultString(UINT uErr)
  1518. {
  1519. LPCTSTR pcsz;
  1520. switch (uErr)
  1521. {
  1522. STRING_CASE(GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  1523. default:
  1524. pcsz = _FormatSzErr("GccResult", uErr);
  1525. break;
  1526. }
  1527. return pcsz;
  1528. }
  1529. LPCTSTR GetMcsResultString(UINT uErr)
  1530. {
  1531. return _FormatSzErr("McsResult", uErr);
  1532. }
  1533. #endif /* DEBUG (T.120 Error routines) */
  1534.