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.

1419 lines
58 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* ERNCGCCC.CPP */
  4. /* */
  5. /* T120 Conference class for the Reference System Node Controller. */
  6. /* */
  7. /* Copyright Data Connection Ltd. 1995 */
  8. /* */
  9. /****************************************************************************/
  10. /* Changes: */
  11. /* */
  12. /* 14Jul95 NFC Created. */
  13. /* 13Sep95 NFC Added handler for GCC_EJECT_USER_INDICATION */
  14. /* 26Sep95 NFC Reset conference state in HandleEjectUser(). */
  15. /* 11Oct95 PM Relax conference termination checks to avoid */
  16. /* "no win" situations. The user wants it down */
  17. /* then bring it down, whatever the state! */
  18. /* */
  19. /****************************************************************************/
  20. #include "precomp.h"
  21. DEBUG_FILEZONE(ZONE_GCC_NC);
  22. #include "ernccons.h"
  23. #include "nccglbl.hpp"
  24. #include "erncvrsn.hpp"
  25. #include "cuserdta.hpp"
  26. #include "ernccm.hpp"
  27. #include "ernctrc.h"
  28. #include "nmremote.h"
  29. static UINT s_nNumericNameCounter = 0;
  30. __inline UINT GetNewNumericNameCounter(void) { return ++s_nNumericNameCounter; }
  31. HRESULT DCRNCConference::
  32. NewT120Conference(void)
  33. {
  34. DebugEntry(DCRNCConference::NewT120Conference);
  35. m_eT120State = T120C_ST_IDLE;
  36. HRESULT hr;
  37. PCONFERENCE pConf;
  38. GCCNumericString pszNewNumericName;
  39. m_ConfName.numeric_string = NULL; // No numeric name yet.
  40. hr = ::GetGCCFromUnicode(m_pwszConfName, &pszNewNumericName, &m_ConfName.text_string);
  41. if (NO_ERROR == hr)
  42. {
  43. if (! ::IsEmptyStringA((LPCSTR) pszNewNumericName))
  44. {
  45. // Conference has a preassigned numeric name.
  46. // Validate that it does not conflict with another
  47. // conferences numeric name.
  48. pConf = g_pNCConfMgr->GetConferenceFromNumber(pszNewNumericName);
  49. if (NULL == pConf)
  50. {
  51. hr = NO_ERROR;
  52. }
  53. else
  54. {
  55. ERROR_OUT(("DCRNCConference::NewT120Conference: conference already exists"));
  56. hr = UI_RC_CONFERENCE_ALREADY_EXISTS;
  57. }
  58. }
  59. else
  60. {
  61. // Conference does not have a numeric name.
  62. // Go get it a unique one.
  63. DBG_SAVE_FILE_LINE
  64. pszNewNumericName = (GCCNumericString)new CHAR[10];
  65. if (NULL != pszNewNumericName)
  66. {
  67. do
  68. {
  69. // Do not allocate a conference number that is the same as
  70. // an existing conference.
  71. // bugbug: T120 should really do this, but it doesn't.
  72. ::wsprintfA((LPSTR) pszNewNumericName, "%u", ::GetNewNumericNameCounter());
  73. pConf = g_pNCConfMgr->GetConferenceFromNumber(pszNewNumericName);
  74. if (NULL == pConf)
  75. {
  76. hr = NO_ERROR; // Name good.
  77. break;
  78. }
  79. }
  80. while (TRUE); // Assumes not a DWORDs worth of conferences active.
  81. }
  82. else
  83. {
  84. ERROR_OUT(("DCRNCConference::NewT120Conference: can't create numeric name"));
  85. hr = UI_RC_OUT_OF_MEMORY;
  86. }
  87. }
  88. }
  89. else
  90. {
  91. ERROR_OUT(("DCRNCConference::NewT120Conference: GetGCCFromUnicode failed, hr=0x%x", (UINT) hr));
  92. }
  93. // Done looking for numeric name, so can now insert into list.
  94. m_ConfName.numeric_string = pszNewNumericName;
  95. // In case of failure, be sure to notify nmcom.
  96. if (NO_ERROR != hr)
  97. {
  98. g_pNCConfMgr->NotifyConferenceComplete(this, m_fIncoming, hr);
  99. }
  100. DebugExitHRESULT(DCRNCConference::NewT120Conference, hr);
  101. return hr;
  102. }
  103. /****************************************************************************/
  104. /* AnnouncePresence() - announce this nodes participation in the */
  105. /* conference. */
  106. /****************************************************************************/
  107. HRESULT DCRNCConference::
  108. AnnouncePresence(void)
  109. {
  110. GCCError GCCrc = GCC_INVALID_CONFERENCE;
  111. HRESULT hr = UI_RC_OUT_OF_MEMORY;
  112. GCCNodeType nodeType;
  113. GCCNodeProperties nodeProperties;
  114. LPWSTR nodeName;
  115. UINT nRecords;
  116. GCCUserData ** ppUserData;
  117. DebugEntry(DCRNCConference::AnnouncePresence);
  118. if (0 != m_nConfID)
  119. {
  120. // bugbug: handle errors that cause failure to announce presence.
  121. // Obtain the local addresses for the local user and
  122. // publish them in the roster.
  123. g_pCallbackInterface->OnUpdateUserData(this);
  124. /************************************************************************/
  125. /* Load the node type, node properties and node name from the RNC INI */
  126. /* file. */
  127. /************************************************************************/
  128. nodeName = NULL;
  129. ::LoadAnnouncePresenceParameters(
  130. &nodeType,
  131. &nodeProperties,
  132. &nodeName,
  133. NULL); // &siteInfo)) : Not used right now.
  134. /************************************************************************/
  135. /* Announce our presence in the conference. */
  136. /************************************************************************/
  137. hr = m_LocalUserData.GetUserDataList(&nRecords, &ppUserData);
  138. if (NO_ERROR == hr)
  139. {
  140. GCCrc = g_pIT120ControlSap->AnnouncePresenceRequest(
  141. m_nConfID,
  142. nodeType,
  143. nodeProperties,
  144. nodeName,
  145. 0, /* number_of_participants */
  146. NULL, //partNameList, /* participant_name_list */
  147. NULL, /* pwszSiteInfo */
  148. 0, /* number_of_network_addresses */
  149. NULL, /* network_address_list */
  150. NULL, //pAltID, /* alternative_node_id */
  151. nRecords,/* number_of_user_data_members */
  152. ppUserData /* user_data_list */
  153. );
  154. hr = ::GetGCCRCDetails(GCCrc);
  155. }
  156. delete nodeName;
  157. }
  158. if (GCC_NO_ERROR != GCCrc)
  159. {
  160. if (GCC_CONFERENCE_NOT_ESTABLISHED == GCCrc ||
  161. GCC_INVALID_CONFERENCE == GCCrc)
  162. {
  163. TRACE_OUT(("DCRNCConference::AnnouncePresence: conf is gone."));
  164. }
  165. else
  166. {
  167. ERROR_OUT(("DCRNCConference::AnnouncePresence: failed, gcc_rc=%u", GCCrc));
  168. }
  169. }
  170. DebugExitHRESULT(DCRNCConference::AnnouncePresence, hr);
  171. return hr;
  172. }
  173. /****************************************************************************/
  174. /* HandleGCCCallback() - see erncgccc.hpp */
  175. /****************************************************************************/
  176. void DCRNCConference::
  177. HandleGCCCallback ( GCCMessage *pGCCMessage )
  178. {
  179. DebugEntry(DCRNCConference::HandleGCCCallback);
  180. TRACE_OUT(("DCRNCConference::HandleGCCCallback: msg id=%u", pGCCMessage->message_type));
  181. /************************************************************************/
  182. /* Note that GCC_CREATE_IND and GCC_INVITE_IND callbacks are handled */
  183. /* higher up the stack by the conference manager and are not passed */
  184. /* onto us. */
  185. /************************************************************************/
  186. switch (pGCCMessage->message_type)
  187. {
  188. case GCC_CREATE_CONFIRM:
  189. HandleCreateConfirm(&(pGCCMessage->u.create_confirm));
  190. break;
  191. case GCC_INVITE_CONFIRM:
  192. HandleInviteConfirm(&(pGCCMessage->u.invite_confirm));
  193. break;
  194. case GCC_ADD_CONFIRM:
  195. HandleAddConfirm(&(pGCCMessage->u.add_confirm));
  196. break;
  197. case GCC_DISCONNECT_INDICATION:
  198. HandleDisconnectInd(&(pGCCMessage->u.disconnect_indication));
  199. break;
  200. case GCC_DISCONNECT_CONFIRM:
  201. HandleDisconnectConfirm(
  202. &(pGCCMessage->u.disconnect_confirm));
  203. break;
  204. case GCC_TERMINATE_INDICATION:
  205. HandleTerminateInd(&(pGCCMessage->u.terminate_indication));
  206. break;
  207. case GCC_TERMINATE_CONFIRM:
  208. HandleTerminateConfirm(&(pGCCMessage->u.terminate_confirm));
  209. break;
  210. case GCC_ANNOUNCE_PRESENCE_CONFIRM:
  211. HandleAnnounceConfirm(&(pGCCMessage->u.announce_presence_confirm));
  212. break;
  213. case GCC_ROSTER_REPORT_INDICATION:
  214. HandleRosterReport(pGCCMessage->u.conf_roster_report_indication.conference_roster);
  215. break;
  216. case GCC_ROSTER_INQUIRE_CONFIRM:
  217. HandleRosterReport(pGCCMessage->u.conf_roster_inquire_confirm.conference_roster);
  218. break;
  219. case GCC_PERMIT_TO_ANNOUNCE_PRESENCE:
  220. HandlePermitToAnnounce(&(pGCCMessage->u.permit_to_announce_presence));
  221. break;
  222. case GCC_EJECT_USER_INDICATION:
  223. HandleEjectUser(&(pGCCMessage->u.eject_user_indication));
  224. break;
  225. case GCC_CONNECTION_BROKEN_INDICATION:
  226. HandleConnectionBrokenIndication(&(pGCCMessage->u.connection_broken_indication));
  227. break;
  228. default :
  229. WARNING_OUT(("Unrecognised event %d", pGCCMessage->message_type));
  230. break;
  231. }
  232. DebugExitVOID(DCRNCConference::HandleGCCCallback);
  233. }
  234. void DCRNCConference::
  235. HandleConnectionBrokenIndication ( ConnectionBrokenIndicationMessage * pConnDownMsg )
  236. {
  237. DebugEntry(DCRNCConference::HandleConnectionBrokenIndication);
  238. // A logical connection in a conference has gone away.
  239. // Find the associated logical connection (if it is still around)
  240. // and Delete() it.
  241. // This function is what causes a modem line to drop when someone
  242. // invited into a conference over a modem leaves the conference.
  243. CLogicalConnection *pConEntry = GetConEntry(pConnDownMsg->connection_handle);
  244. if (NULL != pConEntry)
  245. {
  246. pConEntry->Delete(UI_RC_USER_DISCONNECTED);
  247. }
  248. DebugExitVOID(DCRNCConference::HandleConnectionBrokenIndication);
  249. }
  250. /****************************************************************************/
  251. /* HandleAddConfirm - handle a GCC_ADD_CONFIRM message */
  252. /****************************************************************************/
  253. /****************************************************************************/
  254. /* HandleAnnounceConfirm - handle a GCC_ANNOUNCE_PRESENCE_CONFIRM message */
  255. /****************************************************************************/
  256. void DCRNCConference::
  257. HandleAnnounceConfirm ( AnnouncePresenceConfirmMessage * pAnnounceConf )
  258. {
  259. DebugEntry(DCRNCConference::HandleAnnounceConfirm);
  260. /************************************************************************/
  261. /* Map the return code to a conference return code. */
  262. /************************************************************************/
  263. HRESULT hr = ::GetGCCResultDetails(pAnnounceConf->result);
  264. TRACE_OUT(("GCC event: GCC_ANNOUNCE_PRESENCE_CONFIRM"));
  265. TRACE_OUT(("Result=%u", pAnnounceConf->result));
  266. /************************************************************************/
  267. /* If this failed, tell the base conference that we failed to start. */
  268. /************************************************************************/
  269. if (NO_ERROR != hr)
  270. {
  271. ERROR_OUT(("Failed to announce presence in conference"));
  272. NotifyConferenceComplete(hr);
  273. // bugbug: ??? Should we leave the conference here???
  274. }
  275. /************************************************************************/
  276. /* Now sit and wait for our entry to appear in the conference roster. */
  277. /************************************************************************/
  278. DebugExitHRESULT(DCRNCConference::HandleAnnounceConfirm, hr);
  279. }
  280. /****************************************************************************/
  281. /* HandleCreateConfirm - handle a GCC_CREATE_CONFIRM message. */
  282. /****************************************************************************/
  283. void DCRNCConference::
  284. HandleCreateConfirm ( CreateConfirmMessage * pCreateConfirm )
  285. {
  286. DebugEntry(DCRNCConference::HandleCreateConfirm);
  287. /************************************************************************/
  288. /* Map the GCC result onto CONF_RC_ return code. */
  289. /************************************************************************/
  290. HRESULT hr = ::GetGCCResultDetails(pCreateConfirm->result);
  291. TRACE_OUT(("GCC event: GCC_CREATE_CONFIRM"));
  292. TRACE_OUT(("Result=%u", pCreateConfirm->result));
  293. TRACE_OUT(("Conference ID %ld", pCreateConfirm->conference_id));
  294. /************************************************************************/
  295. /* Result of our attempt to start a new conference */
  296. /************************************************************************/
  297. if (NO_ERROR == hr)
  298. {
  299. /************************************************************************/
  300. /* Store the conference ID. */
  301. /************************************************************************/
  302. m_nConfID = pCreateConfirm->conference_id;
  303. }
  304. else
  305. {
  306. ERROR_OUT(("Error %d creating new conference", hr));
  307. /************************************************************************/
  308. /* Pass any failure result onto the base conference. */
  309. /************************************************************************/
  310. NotifyConferenceComplete(hr);
  311. }
  312. DebugExitVOID(DCRNCConference::HandleCreateConfirm);
  313. }
  314. /****************************************************************************/
  315. /* HandleDisconnectConfirm - handle a GCC_DISCONNECT_CONFIRM message. */
  316. /****************************************************************************/
  317. void DCRNCConference::
  318. HandleDisconnectConfirm ( DisconnectConfirmMessage * pDiscConf )
  319. {
  320. DebugEntry(DCRNCConference::HandleDisconnectConfirm);
  321. /************************************************************************/
  322. /* Check the state. */
  323. /************************************************************************/
  324. if (m_eT120State != T120C_ST_PENDING_DISCONNECT)
  325. {
  326. WARNING_OUT(("Bad state %d, expecting %d",
  327. T120C_ST_PENDING_DISCONNECT,
  328. m_eT120State));
  329. }
  330. /************************************************************************/
  331. /* Map the GCC result onto CONF_RC_ return code. */
  332. /************************************************************************/
  333. TRACE_OUT(("GCC event: GCC_DISCONNECT_CONFIRM"));
  334. TRACE_OUT(("Result=%u", pDiscConf->result));
  335. TRACE_OUT(("Conference ID %ld", pDiscConf->conference_id));
  336. /************************************************************************/
  337. /* We have successsfully left the conference, so tell the base */
  338. /* conference about it. */
  339. /************************************************************************/
  340. g_pNCConfMgr->RemoveConference(this);
  341. DebugExitVOID(DCRNCConference::HandleDisconnectConfirm);
  342. }
  343. /****************************************************************************/
  344. /* HandleDisconnectInd - handle a GCC_DISCONNECT_INDICATION message. */
  345. /****************************************************************************/
  346. void DCRNCConference::
  347. HandleDisconnectInd ( DisconnectIndicationMessage * pDiscInd )
  348. {
  349. DebugEntry(DCRNCConference::HandleDisconnectInd);
  350. /************************************************************************/
  351. /* Check the state. */
  352. /************************************************************************/
  353. TRACE_OUT(("GCC event: GCC_DISCONNECT_INDICATION"));
  354. TRACE_OUT(("Conference ID %d", pDiscInd->conference_id));
  355. TRACE_OUT(("Reason=%u", pDiscInd->reason));
  356. TRACE_OUT(("Disconnected Node ID %d", pDiscInd->disconnected_node_id));
  357. /************************************************************************/
  358. /* If this is our node ID, we have left the conference, tell the CM we */
  359. /* are dead. */
  360. /************************************************************************/
  361. if (pDiscInd->disconnected_node_id == m_nidMyself)
  362. {
  363. WARNING_OUT(("We have been disconnected from conference"));
  364. // m_eT120State = T120C_ST_IDLE;
  365. g_pNCConfMgr->RemoveConference(this);
  366. }
  367. DebugExitVOID(DCRNCConference::HandleDisconnectInd);
  368. }
  369. /****************************************************************************/
  370. /* HandleEjectUser - handle a GCC_EJECT_USER_INDICATION message. */
  371. /****************************************************************************/
  372. void DCRNCConference::
  373. HandleEjectUser ( EjectUserIndicationMessage * pEjectInd )
  374. {
  375. DebugEntry(DCRNCConference::HandleEjectUser);
  376. TRACE_OUT(("GCC_EJECT_USER_INDICATION"));
  377. TRACE_OUT(("Conference ID %ld", pEjectInd->conference_id));
  378. TRACE_OUT(("Ejected node ID %d", pEjectInd->ejected_node_id));
  379. TRACE_OUT(("Reason=%u", pEjectInd->reason));
  380. /************************************************************************/
  381. /* If the ejected node ID is ours, we have been tossed out of the */
  382. /* conference, so tell CM about it. */
  383. /************************************************************************/
  384. if (pEjectInd->ejected_node_id == m_nidMyself)
  385. {
  386. /********************************************************************/
  387. /* Reset the conference state first. */
  388. /********************************************************************/
  389. m_eT120State = T120C_ST_IDLE;
  390. WARNING_OUT(("We have been thrown out of the conference"));
  391. g_pNCConfMgr->RemoveConference(this);
  392. }
  393. DebugExitVOID(DCRNCConference::HandleEjectUser);
  394. }
  395. /****************************************************************************/
  396. /* HandleInviteConfirm - handle a GCC_INVITE_CONFIRM message. */
  397. /****************************************************************************/
  398. void DCRNCConference::
  399. HandleInviteConfirm ( InviteConfirmMessage * pInviteConf )
  400. {
  401. PT120PRODUCTVERSION pVersion;
  402. DebugEntry(DCRNCConference::HandleInviteConfirm);
  403. /************************************************************************/
  404. /* Map the GCC result onto CONF_RC_ return code. */
  405. /************************************************************************/
  406. TRACE_OUT(("GCC event: GCC_INVITE_CONFIRM"));
  407. TRACE_OUT(("Result=%u", pInviteConf->result));
  408. if (pInviteConf->result == GCC_RESULT_SUCCESSFUL)
  409. {
  410. TRACE_OUT(("New node successfully invited into conference"));
  411. ASSERT((ConnectionHandle)pInviteConf->connection_handle);
  412. }
  413. else
  414. {
  415. TRACE_OUT(("Error %d inviting new node into conference", pInviteConf->result));
  416. }
  417. // Notify the base conference that the invite has completed.
  418. pVersion = ::GetVersionData(pInviteConf->number_of_user_data_members,
  419. pInviteConf->user_data_list);
  420. InviteComplete(pInviteConf->connection_handle,
  421. ::GetGCCResultDetails(pInviteConf->result),
  422. pVersion);
  423. DebugExitVOID(DCRNCConference::HandleInviteConfirm);
  424. }
  425. /****************************************************************************/
  426. /* HandleJoinConfirm - handle a GCC_JOIN_CONFIRM message. */
  427. /****************************************************************************/
  428. void DCRNCConference::
  429. HandleJoinConfirm ( JoinConfirmMessage * pJoinConf )
  430. {
  431. DebugEntry(DCRNCConference::HandleJoinConfirm);
  432. m_nConfID = pJoinConf->conference_id;
  433. HRESULT hr;
  434. CLogicalConnection *pConEntry;
  435. PT120PRODUCTVERSION pVersion;
  436. hr = ::GetGCCResultDetails(pJoinConf->result);
  437. TRACE_OUT(("GCC event: GCC_JOIN_CONFIRM"));
  438. TRACE_OUT(("Result=%u", pJoinConf->result));
  439. TRACE_OUT(("Conference ID %ld", pJoinConf->conference_id));
  440. TRACE_OUT(("Locked %d", pJoinConf->conference_is_locked));
  441. TRACE_OUT(("Listed %d", pJoinConf->conference_is_listed));
  442. TRACE_OUT(("Conductible %d", pJoinConf->conference_is_conductible));
  443. TRACE_OUT(("Connection Handle %d", pJoinConf->connection_handle));
  444. TRACE_OUT(("Termination method %d", pJoinConf->termination_method));
  445. pVersion = ::GetVersionData(pJoinConf->number_of_user_data_members,
  446. pJoinConf->user_data_list);
  447. // Check the state.
  448. // If we are not expecting a join confirm at this point, then
  449. // it is most likely that the connection went down whilst we
  450. // were waiting for a join confirmation and we are in the middle of
  451. // telling the user. In this case, just ignore the event.
  452. if (m_eT120State != T120C_ST_PENDING_JOIN_CONFIRM)
  453. {
  454. WARNING_OUT(("Bad state %d, expecting %d",
  455. T120C_ST_PENDING_JOIN_CONFIRM,
  456. m_eT120State));
  457. return;
  458. }
  459. if (NULL == m_ConnList.PeekHead())
  460. {
  461. WARNING_OUT(("Join confirm without a connection"));
  462. return;
  463. }
  464. pConEntry = m_ConnList.PeekHead();
  465. if ((pConEntry->GetState() != CONF_CON_PENDING_JOIN) &&
  466. (pConEntry->GetState() != CONF_CON_PENDING_PASSWORD))
  467. {
  468. if (pConEntry->GetState() != CONF_CON_ERROR)
  469. {
  470. TRACE_OUT(("Join confirm indication ignored"));
  471. }
  472. return;
  473. }
  474. pConEntry->Grab(); // Grab the pending result to the user.
  475. pConEntry->SetConnectionHandle(pJoinConf->connection_handle);
  476. /************************************************************************/
  477. /* Expected result of our attempt to join a conference. */
  478. /* */
  479. /* If it worked, save the conference ID, otherwise tell the base */
  480. /* conference that our attempt to join has failed. */
  481. /************************************************************************/
  482. // There will always be a pConEntry when a JoinConfirm fires,
  483. // even if a physical disconnect is racing the JoinConfirm
  484. // because the physical disconnect handler will cause this code
  485. // to be entered before the physical connection is destroyed,
  486. // as this gives the most accurate return codes.
  487. if (NO_ERROR == hr)
  488. {
  489. TRACE_OUT(("Join worked"));
  490. pConEntry->SetState(CONF_CON_CONNECTED);
  491. m_nConfID = pJoinConf->conference_id;
  492. }
  493. // If the result is an invalid password, then tell the UI
  494. // so that it can put up an invalid password dialog.
  495. // The UI is then supposed to either reissue the join request
  496. // with a new password or end the conference.
  497. // It is done this way to keep the connection up whilst the
  498. // user is entering the password, and not re-connect.
  499. if (UI_RC_INVALID_PASSWORD == hr)
  500. {
  501. // Put the conference in the correct state for allowing
  502. // a second join attempt.
  503. pConEntry->SetState(CONF_CON_PENDING_PASSWORD);
  504. m_eT120State = T120C_ST_IDLE;
  505. m_pbCred = pJoinConf->pb_remote_cred;
  506. m_cbCred = pJoinConf->cb_remote_cred;
  507. // Now tell the user about the result.
  508. g_pCallbackInterface->OnConferenceStarted(this, hr);
  509. }
  510. else
  511. // If the result is an error, then end the conference.
  512. if (NO_ERROR != hr)
  513. {
  514. NotifyConferenceComplete(hr);
  515. }
  516. DebugExitVOID(DCRNCConference::HandleJoinConfirm);
  517. }
  518. /****************************************************************************/
  519. /* HandlePermitToAnnounce - handle a GCC_PERMIT_TO_ANNOUNCE_PRESENCE */
  520. /* message. */
  521. /****************************************************************************/
  522. void DCRNCConference::
  523. HandlePermitToAnnounce ( PermitToAnnouncePresenceMessage * pAnnounce )
  524. {
  525. DebugEntry(DCRNCConference::HandlePermitToAnnounce);
  526. TRACE_OUT(("GCC event: GCC_PERMIT_TO_ANNOUNCE_PRESENCE"));
  527. TRACE_OUT(("Conference ID %ld", pAnnounce->conference_id));
  528. TRACE_OUT(("Node ID %d", pAnnounce->node_id));
  529. /************************************************************************/
  530. /* Store the node ID. */
  531. /************************************************************************/
  532. m_nidMyself = pAnnounce->node_id;
  533. // See if there is a new local connection that needs publishing in the roster.
  534. if (! m_ConnList.IsEmpty())
  535. {
  536. m_ConnList.PeekHead()->NewLocalAddress();
  537. }
  538. /************************************************************************/
  539. /* Announce our presence in the conference. */
  540. /************************************************************************/
  541. HRESULT hr = AnnouncePresence();
  542. if (NO_ERROR == hr)
  543. {
  544. m_eT120State = T120C_ST_PENDING_ROSTER_ENTRY;
  545. }
  546. else
  547. {
  548. ERROR_OUT(("Failed to announce presence in conference, error %d", hr));
  549. // bugbug: end conference?
  550. }
  551. DebugExitVOID(DCRNCConference::HandlePermitToAnnounce);
  552. }
  553. /****************************************************************************/
  554. /* HandleRosterReportInd - handle a GCC_ROSTER_REPORT_INDICATION message. */
  555. /****************************************************************************/
  556. void DCRNCConference::
  557. HandleRosterReport ( GCCConferenceRoster * pConferenceRoster )
  558. {
  559. PNC_ROSTER pRoster;
  560. UINT i;
  561. UINT numRecords = pConferenceRoster->number_of_records;
  562. DebugEntry(DCRNCConference::HandleRosterReport);
  563. TRACE_OUT(("GCC event: GCC_ROSTER_REPORT_INDICATION"));
  564. TRACE_OUT(("Nodes added ? %d", pConferenceRoster->nodes_were_added));
  565. TRACE_OUT(("Nodes removed ? %d", pConferenceRoster->nodes_were_removed));
  566. TRACE_OUT(("Number of records %d", numRecords));
  567. /************************************************************************/
  568. /* If we are still setting up the conference, see whether we have */
  569. /* appeared in the conference roster. */
  570. /************************************************************************/
  571. if (m_eT120State == T120C_ST_PENDING_ROSTER_ENTRY)
  572. {
  573. for (i = 0; i < numRecords ; i++)
  574. {
  575. if (pConferenceRoster->node_record_list[i]->node_id == m_nidMyself)
  576. {
  577. TRACE_OUT(("Found our entry in the roster"));
  578. // We are in the roster! The conference has been
  579. // successfully started so set the state and post
  580. // a message to continue processing.
  581. // This is so that callbacks can be made without getting
  582. // blocked in T120.
  583. m_eT120State = T120C_ST_PENDING_ROSTER_MESSAGE;
  584. g_pNCConfMgr->PostWndMsg(NCMSG_FIRST_ROSTER_RECVD, (LPARAM) this);
  585. }
  586. }
  587. }
  588. /************************************************************************/
  589. /* If we have successfully started, build an RNC roster from the */
  590. /* conference roster and pass it up to the CM. */
  591. /************************************************************************/
  592. if (m_eT120State == T120C_ST_CONF_STARTED)
  593. {
  594. /********************************************************************/
  595. /* Allocate memory for a roster large enough to hold all the */
  596. /* entries. */
  597. /********************************************************************/
  598. DBG_SAVE_FILE_LINE
  599. pRoster = (PNC_ROSTER) new BYTE[(sizeof(NC_ROSTER) +
  600. ((numRecords - 1) * sizeof(NC_ROSTER_NODE_ENTRY)))];
  601. if (pRoster == NULL)
  602. {
  603. ERROR_OUT(("Failed to create new conference roster."));
  604. }
  605. else
  606. {
  607. pRoster->uNumNodes = numRecords;
  608. pRoster->uLocalNodeID = m_nidMyself;
  609. // Add the node details to the roster.
  610. for (i = 0; i < numRecords ; i++)
  611. {
  612. pRoster->nodes[i].uNodeID = pConferenceRoster->node_record_list[i]->node_id;
  613. pRoster->nodes[i].uSuperiorNodeID = pConferenceRoster->node_record_list[i]->superior_node_id;
  614. pRoster->nodes[i].fMCU = (pConferenceRoster->node_record_list[i]->node_type == GCC_MCU);
  615. pRoster->nodes[i].pwszNodeName = pConferenceRoster->node_record_list[i]->node_name;
  616. pRoster->nodes[i].hUserData = pConferenceRoster->node_record_list[i];
  617. // If we have been invited into the conference, then the CLogicalConnection
  618. // list maintained by the conference will not have our superior node's UserID,
  619. // so we need to fill that in here.
  620. if (pRoster->nodes[i].uNodeID == pRoster->uLocalNodeID &&
  621. pRoster->nodes[i].uSuperiorNodeID != 0)
  622. {
  623. // We do have a superior node, so find its CLogicalConnection and fill in the
  624. // UserID. It turns out that the UserIDs of subordinate nodes are filled in
  625. // by another mechanism, so the superior node should be the only entry with
  626. // zero for a UserID.
  627. #ifdef DEBUG
  628. int nSuperiorNode = 0;
  629. #endif
  630. CLogicalConnection * pConEntry;
  631. m_ConnList.Reset();
  632. while (NULL != (pConEntry = m_ConnList.Iterate()))
  633. {
  634. if (pConEntry->GetConnectionNodeID() == 0)
  635. {
  636. pConEntry->SetConnectionNodeID((GCCNodeID)pRoster->nodes[i].uSuperiorNodeID);
  637. #ifdef DEBUG
  638. nSuperiorNode++;
  639. #else
  640. break;
  641. #endif
  642. }
  643. }
  644. ASSERT (nSuperiorNode <= 1);
  645. }
  646. }
  647. NotifyRosterChanged(pRoster);
  648. delete [] pRoster;
  649. }
  650. }
  651. DebugExitVOID(DCRNCConference::HandleRosterReport);
  652. }
  653. /****************************************************************************/
  654. /* HandleTerminateConfirm - handle a GCC_TERMINATE_CONFIRM message. */
  655. /****************************************************************************/
  656. void DCRNCConference::
  657. HandleTerminateConfirm ( TerminateConfirmMessage * pTermConf )
  658. {
  659. DebugEntry(DCRNCConference::HandleTerminateConfirm);
  660. /************************************************************************/
  661. /* Check the state */
  662. /************************************************************************/
  663. if (m_eT120State != T120C_ST_PENDING_TERMINATE)
  664. {
  665. WARNING_OUT(("Bad state: unexpected terminate confirm")); // Go ahead anyway
  666. }
  667. /************************************************************************/
  668. /* Map the GCC result onto CONF_RC_ return code. */
  669. /************************************************************************/
  670. TRACE_OUT(("GCC event: GCC_TERMINATE_CONFIRM"));
  671. TRACE_OUT(("Result=%u", pTermConf->result));
  672. TRACE_OUT(("Conference ID %d", pTermConf->conference_id));
  673. /************************************************************************/
  674. /* If the request failed, reset our state and tell the FE? */
  675. /************************************************************************/
  676. if (pTermConf->result != GCC_RESULT_SUCCESSFUL)
  677. {
  678. ERROR_OUT(("Error %d attempting to terminate conference", pTermConf->result));
  679. m_eT120State = T120C_ST_CONF_STARTED;
  680. }
  681. /************************************************************************/
  682. /* Our request to end the conference has worked - wait for the */
  683. /* termination indication before telling the FE that we have died. */
  684. /************************************************************************/
  685. DebugExitVOID(DCRNCConference::HandleTerminateConfirm);
  686. }
  687. /****************************************************************************/
  688. /* HandleTerminateInd - handle a GCC_TERMINATE_INDICATION message. */
  689. /****************************************************************************/
  690. void DCRNCConference::
  691. HandleTerminateInd ( TerminateIndicationMessage * pTermInd )
  692. {
  693. DebugEntry(DCRNCConference::HandleTerminateInd);
  694. TRACE_OUT(("GCC event: GCC_TERMINATE_INDICATION"));
  695. TRACE_OUT(("Conference ID %d", pTermInd->conference_id));
  696. TRACE_OUT(("Requesting node ID %d", pTermInd->requesting_node_id));
  697. TRACE_OUT(("Reason=%u", pTermInd->reason));
  698. /************************************************************************/
  699. /* The conference has ended beneath us. Reset our internal state and */
  700. /* tell the base conference about it. */
  701. /************************************************************************/
  702. m_eT120State = T120C_ST_IDLE;
  703. g_pNCConfMgr->RemoveConference(this);
  704. DebugExitVOID(DCRNCConference::HandleTerminateInd);
  705. }
  706. HRESULT DCRNCConference::
  707. RefreshRoster(void)
  708. {
  709. DebugEntry(DCRNCConference::RefreshRoster);
  710. // Check the state.
  711. if (m_eT120State != T120C_ST_CONF_STARTED)
  712. {
  713. ERROR_OUT(("Bad state: refresh roster requested before conference up"));
  714. return(UI_RC_CONFERENCE_NOT_READY);
  715. }
  716. // Issue the request
  717. GCCError GCCrc = g_pIT120ControlSap->ConfRosterInqRequest(m_nConfID); // Conference ID
  718. // Handle the result
  719. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  720. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfRosterInqRequest, rc=%d", GCCrc));
  721. DebugExitHRESULT(DCRNCConference::RefreshRoster, hr);
  722. return hr;
  723. }
  724. /****************************************************************************/
  725. /* Invite() - see erncgccc.hpp */
  726. /****************************************************************************/
  727. HRESULT DCRNCConference::
  728. T120Invite
  729. (
  730. LPSTR pszNodeAddress,
  731. BOOL fSecure,
  732. CNCUserDataList *pUserDataInfoList,
  733. ConnectionHandle *phInviteReqConn
  734. )
  735. {
  736. GCCError GCCrc = GCC_NO_ERROR;
  737. HRESULT hr;
  738. UINT nUserDataRecords = 0;
  739. GCCUserData **ppInfoUserData = NULL;
  740. UINT nData;
  741. PVOID pData;
  742. char szAddress[RNC_MAX_NODE_STRING_LEN];
  743. DebugEntry(DCRNCConference::T120Invite);
  744. ASSERT(phInviteReqConn != NULL);
  745. /************************************************************************/
  746. /* Check the state. */
  747. /************************************************************************/
  748. if (m_eT120State != T120C_ST_CONF_STARTED)
  749. {
  750. ERROR_OUT(("Bad state: refresh roster requested before conference up"));
  751. return(UI_RC_CONFERENCE_NOT_READY);
  752. }
  753. /************************************************************************/
  754. /* Build the address from the node details. */
  755. /************************************************************************/
  756. ::BuildAddressFromNodeDetails(pszNodeAddress, &szAddress[0]);
  757. /************************************************************************/
  758. /* Invite the specified node into the conference. */
  759. /************************************************************************/
  760. LPWSTR pwszNodeName;
  761. // If there is any user data to be sent
  762. if (pUserDataInfoList)
  763. {
  764. // Add versioning data
  765. if (NO_ERROR == ::GetUserData(g_nVersionRecords, g_ppVersionUserData, &g_csguidVerInfo, &nData, &pData))
  766. {
  767. pUserDataInfoList->AddUserData(&g_csguidVerInfo, nData, pData);
  768. }
  769. pUserDataInfoList->GetUserDataList(&nUserDataRecords,&ppInfoUserData);
  770. }
  771. else
  772. {
  773. ppInfoUserData = g_ppVersionUserData;
  774. nUserDataRecords = g_nVersionRecords;
  775. }
  776. if (NULL != (pwszNodeName = ::GetNodeName()))
  777. {
  778. GCCrc = g_pIT120ControlSap->ConfInviteRequest(
  779. m_nConfID,
  780. pwszNodeName, // caller_identifier
  781. NULL, // calling_address
  782. &szAddress[0], // called_address
  783. fSecure, // secure connection?
  784. nUserDataRecords, // number_of_user_data_members
  785. ppInfoUserData, // user_data_list
  786. phInviteReqConn // returned connection_handle
  787. );
  788. hr = ::GetGCCRCDetails(GCCrc);
  789. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfInviteRequest, rc=%d", GCCrc));
  790. TRACE_OUT(("Transport handle %d", (UINT) *phInviteReqConn));
  791. TRACE_OUT(("Called address '%s'", &szAddress[0]));
  792. delete pwszNodeName;
  793. }
  794. else
  795. {
  796. hr = UI_RC_OUT_OF_MEMORY;
  797. }
  798. DebugExitHRESULT(DCRNCConference::T120Invite, hr);
  799. return hr;
  800. }
  801. /****************************************************************************/
  802. /* Terminate() - see erncgccc.hpp */
  803. /****************************************************************************/
  804. #if 0 // LONCHANC
  805. HRESULT DCRNCConference::
  806. Terminate(void)
  807. {
  808. DebugEntry(DCRNCConference::Terminate);
  809. /************************************************************************/
  810. /* Request to terminate the conference. */
  811. /************************************************************************/
  812. GCCError GCCrc = ::GCCConferenceTerminateRequest(m_nConfID, GCC_REASON_USER_INITIATED);
  813. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  814. TRACE_OUT(("GCC call: GCCConferenceTerminateRequest, rc=%d", GCCrc));
  815. if (NO_ERROR == hr)
  816. {
  817. // Set the state to show we are about to die.
  818. m_eT120State = T120C_ST_PENDING_TERMINATE;
  819. }
  820. else
  821. {
  822. ERROR_OUT(("Failed to terminate conference, GCC error %d", GCCrc));
  823. }
  824. DebugExitHRESULT(DCRNCConference::Terminate, hr);
  825. return hr;
  826. }
  827. #endif // 0
  828. /****************************************************************************/
  829. /* SendText() - see erncgccc.hpp */
  830. /****************************************************************************/
  831. #if 0 // LONCHANC: not used
  832. HRESULT DCRNCConference::
  833. SendText
  834. (
  835. LPWSTR pwszTextMsg,
  836. GCCNodeID node_id
  837. )
  838. {
  839. DebugEntry(DCRNCConference::SendText);
  840. /************************************************************************/
  841. /* Request to send text to node in the conference. */
  842. /************************************************************************/
  843. GCCError GCCrc = ::GCCTextMessageRequest(m_nConfID, pwszTextMsg, node_id);
  844. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  845. TRACE_OUT(("GCC call: GCCTextMessageRequest, rc=%d", GCCrc));
  846. if (NO_ERROR != hr)
  847. {
  848. ERROR_OUT(("Failed to send text to user, GCC error %d", GCCrc));
  849. }
  850. DebugExitHRESULT(DCRNCConference::SendText, hr);
  851. return hr;
  852. }
  853. #endif // 0
  854. #if 0 // LONCHANC: not used
  855. HRESULT DCRNCConference::
  856. TimeRemaining
  857. (
  858. UINT nTimeRemaining,
  859. GCCNodeID nidDestination
  860. )
  861. {
  862. DebugEntry(DCRNCConference::TimeRemaining);
  863. /************************************************************************/
  864. /* Request remaining time of the conference */
  865. /************************************************************************/
  866. GCCError GCCrc = g_pIT120ControlSap->ConfTimeRemainingRequest(m_nConfID, nTimeRemaining, nidDestination);
  867. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  868. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfTimeRemainingRequest, rc=%d", GCCrc));
  869. if (NO_ERROR != hr)
  870. {
  871. ERROR_OUT(("Failed to send the time remaining to user, GCC error %d", GCCrc));
  872. }
  873. DebugExitHRESULT(DCRNCConference::TimeRemaining, hr);
  874. return hr;
  875. }
  876. #endif // 0
  877. /****************************************************************************/
  878. /* Join() - see erncgccc.hpp */
  879. /****************************************************************************/
  880. HRESULT DCRNCConference::
  881. T120Join
  882. (
  883. LPSTR pszNodeAddress,
  884. BOOL fSecure,
  885. LPCWSTR conferenceName,
  886. CNCUserDataList *pUserDataInfoList,
  887. LPCWSTR wszPassword
  888. // REQUEST_HANDLE *phRequest
  889. )
  890. {
  891. GCCError GCCrc = GCC_NO_ERROR;
  892. HRESULT hr = NO_ERROR;
  893. ConnectionHandle connectionHandle = 0;
  894. GCCChallengeRequestResponse Password_Challenge;
  895. GCCChallengeRequestResponse *pPassword_Challenge = NULL;
  896. Password_Challenge.u.password_in_the_clear.numeric_string = NULL;
  897. UINT nUserDataRecords = 0;
  898. GCCUserData **ppInfoUserData = NULL;
  899. UINT nData;
  900. LPVOID pData;
  901. char szAddress[RNC_MAX_NODE_STRING_LEN];
  902. DebugEntry(DCRNCConference::T120Join);
  903. /************************************************************************/
  904. /* Check the state */
  905. /************************************************************************/
  906. ASSERT(m_eT120State == T120C_ST_IDLE);
  907. /************************************************************************/
  908. /* Build the address from the node details. */
  909. /************************************************************************/
  910. ::BuildAddressFromNodeDetails(pszNodeAddress, &szAddress[0]);
  911. // Set up password rubbish
  912. if (! ::IsEmptyStringW(wszPassword))
  913. {
  914. pPassword_Challenge = & Password_Challenge;
  915. Password_Challenge.password_challenge_type = GCC_PASSWORD_IN_THE_CLEAR;
  916. hr = ::GetGCCFromUnicode(wszPassword,
  917. &Password_Challenge.u.password_in_the_clear.numeric_string,
  918. &Password_Challenge.u.password_in_the_clear.text_string);
  919. }
  920. if (NO_ERROR == hr)
  921. {
  922. LPWSTR pwszNodeName;
  923. if (NULL != (pwszNodeName = ::GetNodeName()))
  924. {
  925. // Do not specify a numeric and text name when trying
  926. // to join a conference because if a numeric name was
  927. // autogenerated, rather than specified by the user,
  928. // then it will not be correct on the node being joined.
  929. // Consequently, remove the numeric name from the request
  930. // and rediscover it, if needed, from the GCC_JOIN_CONFIRM indication
  931. // (this is not currently done).
  932. if ((m_ConfName.numeric_string != NULL) && (m_ConfName.text_string != NULL))
  933. {
  934. delete m_ConfName.numeric_string;
  935. m_ConfName.numeric_string = NULL;
  936. }
  937. // If there is any user data to be sent
  938. if (pUserDataInfoList)
  939. {
  940. // Add versioning data
  941. if (NO_ERROR == ::GetUserData(g_nVersionRecords, g_ppVersionUserData, &g_csguidVerInfo, &nData, &pData))
  942. {
  943. pUserDataInfoList->AddUserData(&g_csguidVerInfo, nData, pData);
  944. }
  945. pUserDataInfoList->GetUserDataList(&nUserDataRecords,&ppInfoUserData);
  946. }
  947. else
  948. {
  949. ppInfoUserData = g_ppVersionUserData;
  950. nUserDataRecords = g_nVersionRecords;
  951. }
  952. GCCrc = g_pIT120ControlSap->ConfJoinRequest(&m_ConfName,
  953. NULL, // called_node_modifier
  954. NULL, // calling_node_modifier
  955. NULL, // convener_password
  956. pPassword_Challenge, // password_challenge
  957. pwszNodeName, // caller_identifier
  958. NULL, // calling_address
  959. &szAddress[0], // called_address
  960. fSecure,
  961. NULL, // domain_parameters
  962. 0, // number_of_network_addresses
  963. NULL, // local_network_address_list
  964. nUserDataRecords, // number_of_user_data_members
  965. ppInfoUserData, // user_data_list
  966. &connectionHandle, // connection_handle
  967. &m_nConfID
  968. );
  969. delete pwszNodeName;
  970. hr = ::GetGCCRCDetails(GCCrc);
  971. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfJoinRequest, rc=%d", GCCrc));
  972. TRACE_OUT(("Called address '%s'", &szAddress[0]));
  973. if (NO_ERROR == hr)
  974. {
  975. m_eT120State = T120C_ST_PENDING_JOIN_CONFIRM;
  976. }
  977. }
  978. else
  979. {
  980. hr = UI_RC_OUT_OF_MEMORY;
  981. }
  982. }
  983. delete Password_Challenge.u.password_in_the_clear.numeric_string;
  984. DebugExitHRESULT(DCRNCConference::T120Join, hr);
  985. return hr;
  986. }
  987. /****************************************************************************/
  988. /* StartLocal() - see erncgccc.hpp */
  989. /****************************************************************************/
  990. HRESULT DCRNCConference::
  991. T120StartLocal(BOOL fSecure)
  992. {
  993. GCCError GCCrc;
  994. HRESULT hr;
  995. ConnectionHandle hConnection = 0;
  996. GCCConferencePrivileges priv = {1,1,1,1,1};
  997. WCHAR pwszRDS[] = RDS_CONFERENCE_DESCRIPTOR;
  998. DebugEntry(DCRNCConference::T120StartLocal);
  999. /************************************************************************/
  1000. /* Call GCC_Conference_Create_Request and wait for the confirmation */
  1001. /* event. */
  1002. /************************************************************************/
  1003. GCCConfCreateRequest ccr;
  1004. ::ZeroMemory(&ccr, sizeof(ccr));
  1005. ccr.Core.conference_name = &m_ConfName;
  1006. // ccr.Core.conference_modifier = NULL;
  1007. // ccr.Core.use_password_in_the_clear = 0;
  1008. // ccr.Core.conference_is_locked = 0;
  1009. ccr.Core.conference_is_listed = 1;
  1010. // ccr.Core.conference_is_conductible = 0;
  1011. ccr.Core.termination_method = GCC_MANUAL_TERMINATION_METHOD;
  1012. ccr.Core.conduct_privilege_list = &priv; // Conductor priveleges
  1013. ccr.Core.conduct_mode_privilege_list = &priv; // Member priveleges in conducted conference
  1014. ccr.Core.non_conduct_privilege_list = &priv; // Member priveleges in non-conducted conference
  1015. // ccr.Core.pwszConfDescriptor = NULL;
  1016. OSVERSIONINFO osvi;
  1017. osvi.dwOSVersionInfoSize = sizeof(osvi);
  1018. if (FALSE == ::GetVersionEx (&osvi))
  1019. {
  1020. ERROR_OUT(("GetVersionEx() failed!"));
  1021. }
  1022. if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && g_bRDS)
  1023. {
  1024. ccr.Core.pwszConfDescriptor = pwszRDS;
  1025. }
  1026. // ccr.Core.pwszCallerID = NULL;
  1027. // ccr.Core.calling_address = NULL;
  1028. // ccr.Core.called_address = NULL;
  1029. // ccr.Core.domain_parameters = NULL;
  1030. // ccr.Core.number_of_network_addresses = 0;
  1031. // ccr.Core.network_address_list = NULL;
  1032. ccr.Core.connection_handle = &hConnection;
  1033. // ccr.convener_password = NULL;
  1034. // ccr.password = NULL;
  1035. // ccr.number_of_user_data_members = 0;
  1036. // ccr.user_data_list = NULL;
  1037. ccr.fSecure = fSecure;
  1038. GCCrc = g_pIT120ControlSap->ConfCreateRequest(&ccr, &m_nConfID);
  1039. hr = ::GetGCCRCDetails(GCCrc);
  1040. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfCreateRequest"));
  1041. TRACE_OUT(("LOCAL CONFERENCE"));
  1042. TRACE_OUT(("Connection handle %d", (UINT) hConnection));
  1043. /************************************************************************/
  1044. /* Map the GCC return code to a conference return code. */
  1045. /************************************************************************/
  1046. if (NO_ERROR == hr)
  1047. {
  1048. // Set the state.
  1049. m_eT120State = T120C_ST_PENDING_START_CONFIRM;
  1050. }
  1051. else
  1052. {
  1053. ERROR_OUT(("GCC Error %d starting local conference", GCCrc));
  1054. }
  1055. DebugExitHRESULT(DCRNCConference::T120StartLocal, hr);
  1056. return hr;
  1057. }
  1058. // LONCHANC: please do not remove this chunk of code.
  1059. #ifdef ENABLE_START_REMOTE
  1060. /****************************************************************************/
  1061. /* StartRemote() - see erncgccc.hpp */
  1062. /****************************************************************************/
  1063. HRESULT DCRNCConference::
  1064. T120StartRemote ( LPSTR pszNodeAddress )
  1065. {
  1066. // Do not allow attempts to create T120 conferences on remote nodes.
  1067. // The code that was written to do this is left here in case someone
  1068. // wants to resurrect this functionality in the future.
  1069. GCCError GCCrc;
  1070. HRESULT hr;
  1071. ConnectionHandle connectionHandle = 0;
  1072. GCCConferencePrivileges priv = {1,1,1,1,1};
  1073. char szAddress[RNC_MAX_NODE_STRING_LEN];
  1074. DebugEntry(DCRNCConference::T120StartRemote);
  1075. /************************************************************************/
  1076. /* Build the address from the node details. */
  1077. /************************************************************************/
  1078. ::BuildAddressFromNodeDetails(pszNodeAddress, &szAddress[0]);
  1079. /************************************************************************/
  1080. /* Call GCC_Conference_Create_Request and wait for the confirmation */
  1081. /* event. */
  1082. /************************************************************************/
  1083. TRACE_OUT(("Starting New Remote Conference..."));
  1084. /************************************************************************/
  1085. /* Call GCC_Conference_Create_Request and wait for the confirmation */
  1086. /* event. */
  1087. /************************************************************************/
  1088. GCCConfCreateRequest ccr;
  1089. ::ZeroMemory(&ccr, sizeof(ccr));
  1090. ccr.Core.conference_name = &m_ConfName;
  1091. ccr.Core.conference_modifier = NULL;
  1092. // ccr.Core.use_password_in_the_clear = 0;
  1093. // ccr.Core.conference_is_locked = 0;
  1094. ccr.Core.conference_is_listed = 1;
  1095. ccr.Core.conference_is_conductible = 1;
  1096. ccr.Core.termination_method = GCC_AUTOMATIC_TERMINATION_METHOD;
  1097. ccr.Core.conduct_privilege_list = &priv; // Conductor priveleges
  1098. ccr.Core.conduct_mode_privilege_list = &priv; // Member priveleges in conducted conference
  1099. ccr.Core.non_conduct_privilege_list = &priv; // Member priveleges in non-conducted conference
  1100. // ccr.Core.pwszConfDescriptor = NULL;
  1101. // ccr.Core.pwszCallerID = NULL;
  1102. // ccr.Core.calling_address = NULL;
  1103. ccr.Core.called_address = &szAddress[0];
  1104. // ccr.Core.domain_parameters = NULL;
  1105. // ccr.Core.number_of_network_addresses = 0;
  1106. // ccr.Core.network_address_list = NULL;
  1107. ccr.Core.connection_handle = &connectionHandle;
  1108. // ccr.convener_password = NULL;
  1109. // ccr.password = NULL;
  1110. // ccr.number_of_user_data_members = 0;
  1111. // ccr.user_data_list = NULL;
  1112. GCCrc = g_pIT120ControlSap->ConfCreateRequest(&ccr, &m_nConfID);
  1113. hr = ::GetGCCRCDetails(GCCrc);
  1114. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfCreateRequest"));
  1115. TRACE_OUT(("Called address '%s'", &szAddress[0]));
  1116. TRACE_OUT(("Connection handle %d", connectionHandle));
  1117. /************************************************************************/
  1118. /* Map the GCC return code to a conference return code. */
  1119. /************************************************************************/
  1120. if (NO_ERROR != hr)
  1121. {
  1122. ERROR_OUT(("GCC Error %d starting local conference", GCCrc));
  1123. }
  1124. else
  1125. {
  1126. // Set the state.
  1127. m_eT120State = T120C_ST_PENDING_START_CONFIRM;
  1128. }
  1129. DebugExitHRESULT(DCRNCConference::T120StartRemote, hr);
  1130. return hr;
  1131. }
  1132. #endif // ENABLE_START_REMOTE
  1133. void LoadAnnouncePresenceParameters
  1134. (
  1135. GCCNodeType *nodeType,
  1136. GCCNodeProperties *nodeProperties,
  1137. LPWSTR *ppwszNodeName,
  1138. LPWSTR *ppwszSiteInformation
  1139. )
  1140. {
  1141. DebugEntry(LoadAnnouncePresenceParameters);
  1142. /* The following key does not currently exist.
  1143. * If we ever decide to use it, we should un-comment this call
  1144. * and following calls in this function, designed to access the
  1145. * registry entries under this key.
  1146. * Some of the rest of the registry calls are under #if 0, #else, #endif
  1147. * clauses.
  1148. */
  1149. #if 0
  1150. RegEntry ConferenceKey(DATA_CONFERENCING_KEY, HKEY_LOCAL_MACHINE);
  1151. #endif // 0
  1152. // Get the type of node controller.
  1153. if (nodeType)
  1154. {
  1155. #if 0
  1156. *nodeType = ConferenceKey.GetNumber(REGVAL_NODE_CONTROLLER_MODE, GCC_MULTIPORT_TERMINAL);
  1157. #else // 0
  1158. *nodeType = GCC_MULTIPORT_TERMINAL;
  1159. #endif // 0
  1160. TRACE_OUT(("Node type %d", *nodeType));
  1161. }
  1162. // Load the node properties.
  1163. if (nodeProperties)
  1164. {
  1165. #if 0
  1166. *nodeProperties = ConferenceKey.GetNumber(REGVAL_NODE_CONTROLLER_PROPERTY,
  1167. GCC_NEITHER_PERIPHERAL_NOR_MANAGEMENT);
  1168. #else // 0
  1169. *nodeProperties = GCC_NEITHER_PERIPHERAL_NOR_MANAGEMENT;
  1170. #endif // 0
  1171. TRACE_OUT(("Node properties %d", *nodeProperties));
  1172. }
  1173. // Get site information.
  1174. // Ignore if no site info.
  1175. #if 0
  1176. if (ppwszSiteInformation)
  1177. {
  1178. *ppwszSiteInformation = ::AnsiToUnicode(ConferenceKey.GetString(REGVAL_NODE_CONTROLLER_SITE_INFO));
  1179. }
  1180. #endif // 0
  1181. if (ppwszNodeName)
  1182. {
  1183. // Rely upon GetNodeName returning NULL pointer if error.
  1184. // Note that successful if got this, so no need to free on error.
  1185. *ppwszNodeName = ::GetNodeName();
  1186. }
  1187. DebugExitVOID(LoadAnnouncePresenceParameters);
  1188. }
  1189. /****************************************************************************/
  1190. /* Build the address from the node details. */
  1191. /****************************************************************************/
  1192. void BuildAddressFromNodeDetails
  1193. (
  1194. LPSTR pszNodeAddress,
  1195. LPSTR pszDstAddress
  1196. )
  1197. {
  1198. DebugEntry(BuildAddressFromNodeDetails);
  1199. /************************************************************************/
  1200. /* GCC address take the form <transport type>:address. */
  1201. /************************************************************************/
  1202. TRACE_OUT(("BuildAddressFromNodeDetails:: TCP address '%s'", pszNodeAddress));
  1203. /************************************************************************/
  1204. /* Add the prefix for this transport type. */
  1205. /************************************************************************/
  1206. /************************************************************************/
  1207. /* Add the separator followed by the actual address. */
  1208. /************************************************************************/
  1209. ::lstrcpyA(pszDstAddress, RNC_GCC_TRANSPORT_AND_SEPARATOR);
  1210. ::lstrcatA(pszDstAddress, pszNodeAddress);
  1211. DebugExitVOID(BuildAddressFromNodeDetails);
  1212. }
  1213.