Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1750 lines
37 KiB

  1. #include "precomp.h"
  2. // NetMeeting stuff
  3. #include "AtlExeModule.h"
  4. #include "ConfUtil.h"
  5. #include "NmLdap.h"
  6. #include "call.h"
  7. #include "common.h"
  8. #include "ConfMan.h"
  9. #include "cmd.h"
  10. #include "conf.h"
  11. #include "iAppLdr.h"
  12. #include "confroom.h"
  13. #include "ConfPolicies.h"
  14. #include "cmd.h"
  15. #include "ConfWnd.h"
  16. #include "Taskbar.h"
  17. #include "certui.h"
  18. // NetMeeting SDK includes
  19. #include "NmEnum.h"
  20. #include "NmManager.h"
  21. #include "NmConference.h"
  22. #include "NmCall.h"
  23. #include "SDKWindow.h"
  24. #include "dlgCall2.h"
  25. bool g_bSDKPostNotifications;
  26. extern BOOL g_fLoggedOn;
  27. extern INmSysInfo2 * g_pNmSysInfo;
  28. extern GUID g_csguidSecurity;
  29. //static
  30. CSimpleArray<CNmManagerObj*>* CNmManagerObj::ms_pManagerObjList = NULL;
  31. bool g_bOfficeModeSuspendNotifications = false;
  32. DWORD CNmManagerObj::ms_dwID = 1;
  33. BOOL InitAppletSDK(void);
  34. void CleanupAppletSDK(void);
  35. ///////////////////////////////////////////////
  36. // Construction\Destruction
  37. ///////////////////////////////////////////////
  38. CNmManagerObj::CNmManagerObj()
  39. : m_bInitialized(false),
  40. m_chCaps(NMCH_NONE),
  41. m_bNmActive(false),
  42. m_bSentConferenceCreated(false),
  43. m_dwID(0),
  44. m_dwSysInfoID(0),
  45. m_uOptions(0)
  46. {
  47. DBGENTRY(CNmManagerObj::CNmManagerObj);
  48. CNmManagerObj* p = const_cast<CNmManagerObj*>(this);
  49. ms_pManagerObjList->Add(p);
  50. DBGEXIT(CNmManagerObj::CNmManagerObj);
  51. }
  52. CNmManagerObj::~CNmManagerObj()
  53. {
  54. DBGENTRY(CNmManagerObj::~CNmManagerObj);
  55. CNmManagerObj* p = const_cast<CNmManagerObj*>(this);
  56. ms_pManagerObjList->Remove(p);
  57. // Free our conferencing objects
  58. while(m_SDKConferenceObjs.GetSize())
  59. {
  60. CComPtr<INmConference> sp = m_SDKConferenceObjs[0];
  61. m_SDKConferenceObjs.RemoveAt(0);
  62. sp.p->Release();
  63. }
  64. // Free our conferencing objects
  65. while(m_SDKCallObjs.GetSize())
  66. {
  67. CComPtr<INmCall> sp = m_SDKCallObjs[0];
  68. m_SDKCallObjs.RemoveAt(0);
  69. sp.p->Release();
  70. }
  71. m_spInternalNmManager = NULL;
  72. DBGEXIT(CNmManagerObj::~CNmManagerObj);
  73. }
  74. HRESULT CNmManagerObj::FinalConstruct()
  75. {
  76. DBGENTRY(CNmManagerObj::FinalContstruct);
  77. HRESULT hr = S_OK;
  78. m_bInitialized = false;
  79. m_dwInternalNmManagerAdvise = 0;
  80. DBGEXIT_HR(CNmManagerObj::FinalContstruct,hr);
  81. return hr;
  82. }
  83. ULONG CNmManagerObj::InternalRelease()
  84. {
  85. ATLASSERT(m_dwRef > 0);
  86. --m_dwRef;
  87. if((1 == m_dwRef) && m_dwInternalNmManagerAdvise)
  88. {
  89. ++m_dwRef;
  90. DWORD dwAdvise = m_dwInternalNmManagerAdvise;
  91. m_dwInternalNmManagerAdvise = 0;
  92. AtlUnadvise(m_spInternalNmManager, IID_INmManagerNotify, dwAdvise);
  93. --m_dwRef;
  94. }
  95. return m_dwRef;
  96. }
  97. void CNmManagerObj::FinalRelease()
  98. {
  99. DBGENTRY(CNmManagerObj::FinalRelease);
  100. if(m_bInitialized)
  101. {
  102. switch(m_uOptions)
  103. {
  104. case NM_INIT_CONTROL:
  105. // Even though we have the NM_INIT_CONTROL flag set here
  106. // We may not me in INIT_CONTROL mode. NetMeeting may have
  107. // already been up when we initialized. In that case the UI is active
  108. if(_Module.InitControlMode())
  109. {
  110. // If we are the last NmManager object with NM_INIT_CONTROL, then
  111. // we should switch the UI mode away from InitControl
  112. if((GetManagerCount(NM_INIT_CONTROL) == 1))
  113. {
  114. if(!_Module.IsSDKCallerRTC())
  115. {
  116. _Module.SetInitControlMode(FALSE);
  117. ::AddTaskbarIcon(::GetHiddenWindow());
  118. }
  119. }
  120. }
  121. break;
  122. case NM_INIT_OBJECT:
  123. // Check to see if this is the last "office" client
  124. if (GetManagerCount(NM_INIT_OBJECT) == 1)
  125. {
  126. CConfMan::AllowAV(TRUE);
  127. }
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133. DBGEXIT(CNmManagerObj::FinalRelease);
  134. }
  135. /*static*/ HRESULT CNmManagerObj::InitSDK()
  136. {
  137. DBGENTRY(CNmManagerObj::InitSDK);
  138. HRESULT hr = S_OK;
  139. g_bSDKPostNotifications = false;
  140. ms_pManagerObjList = new CSimpleArray<CNmManagerObj*>;
  141. if(!ms_pManagerObjList)
  142. {
  143. hr = E_OUTOFMEMORY;
  144. }
  145. ::InitAppletSDK();
  146. InitPluggableTransportSDK();
  147. DBGEXIT_HR(CNmManagerObj::InitSDK,hr);
  148. return hr;
  149. }
  150. /*static*/void CNmManagerObj::CleanupSDK()
  151. {
  152. DBGENTRY(CNmManagerObj::CleanupSDK);
  153. ::CleanupAppletSDK();
  154. CleanupPluggableTransportSDK();
  155. delete ms_pManagerObjList;
  156. DBGEXIT(CNmManagerObj::CleanupSDK);
  157. }
  158. ///////////////////////////////////////////////
  159. // INmManager methods
  160. ///////////////////////////////////////////////
  161. STDMETHODIMP CNmManagerObj::Initialize( ULONG * puOptions, ULONG *puchCaps)
  162. {
  163. DBGENTRY(CNmManagerObj::Initialize);
  164. HRESULT hr = S_OK;
  165. // If the remote control service is running, this will bring up a dialog
  166. // that the user can choose weather or not to kill the remote control session
  167. // If they do want to kill the session then the mananger object will initialize properly
  168. if(!CheckRemoteControlService())
  169. {
  170. return E_FAIL;
  171. }
  172. m_uOptions = puOptions ? *puOptions : NM_INIT_NORMAL;
  173. if(puOptions && (*puOptions > NM_INIT_BACKGROUND))
  174. {
  175. hr = E_INVALIDARG;
  176. goto end;
  177. }
  178. if(!m_bInitialized)
  179. {
  180. bool bStartedNetMeeting = false;
  181. if(!g_pInternalNmManager)
  182. {
  183. if(NM_INIT_NO_LAUNCH == m_uOptions)
  184. {
  185. // We don't launch NetMeeting in this case...
  186. m_bNmActive = false;
  187. goto end;
  188. }
  189. if (NM_INIT_CONTROL == m_uOptions)
  190. {
  191. _Module.SetInitControlMode(TRUE);
  192. }
  193. hr = InitConfExe(NM_INIT_NORMAL == m_uOptions);
  194. bStartedNetMeeting = SUCCEEDED(hr);
  195. }
  196. if(SUCCEEDED(hr))
  197. {
  198. if(NM_INIT_OBJECT == m_uOptions)
  199. {
  200. if (!_Module.IsUIVisible())
  201. {
  202. CConfMan::AllowAV(FALSE);
  203. }
  204. }
  205. m_bNmActive = true;
  206. CFt::EnsureLoadFtApplet();
  207. m_spInternalNmManager = g_pInternalNmManager;
  208. // The old NetMeeting ignored this param...
  209. // for the time being, we are ignoring it too.
  210. //m_chCaps = puchCaps ? *puchCaps : NMCH_ALL;
  211. m_chCaps = NMCH_ALL;
  212. hr = AtlAdvise(m_spInternalNmManager,GetUnknown(),IID_INmManagerNotify, &m_dwInternalNmManagerAdvise);
  213. }
  214. }
  215. else
  216. {
  217. hr = E_FAIL;
  218. }
  219. end:
  220. m_bInitialized = SUCCEEDED(hr);
  221. if(m_bInitialized)
  222. {
  223. INmConference2* pConf = ::GetActiveConference();
  224. if(pConf)
  225. {
  226. ConferenceCreated(pConf);
  227. // If there is no manager notify hooked in, we simply
  228. // sync up with the Internal conference object state
  229. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  230. if((0 == pCP->m_vec.GetSize()) && !m_bSentConferenceCreated)
  231. {
  232. // It must be the first conference, because we are newly-initialized
  233. ASSERT(m_SDKConferenceObjs[0]);
  234. // Sinc up the channels, etc.
  235. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[0])->FireNotificationsToSyncToInternalObject();
  236. }
  237. }
  238. }
  239. DBGEXIT_HR(CNmManagerObj::Initialize,hr);
  240. return hr;
  241. }
  242. // This is not guarenteed to work if called from conf.exe's process!!!
  243. STDMETHODIMP CNmManagerObj::GetSysInfo(INmSysInfo **ppSysInfo)
  244. {
  245. DBGENTRY(CNmManagerObj::GetSysInfo);
  246. HRESULT hr = S_OK;
  247. hr = CoCreateInstance(CLSID_NmSysInfo, NULL, CLSCTX_ALL, IID_INmSysInfo, reinterpret_cast<void**>(ppSysInfo));
  248. if(*ppSysInfo)
  249. {
  250. m_dwID = ++ms_dwID;
  251. com_cast<IInternalSysInfoObj>(*ppSysInfo)->SetID(m_dwID);
  252. }
  253. DBGEXIT_HR(CNmManagerObj::GetSysInfo,hr);
  254. return hr;
  255. }
  256. STDMETHODIMP CNmManagerObj::CreateConference(INmConference **ppConference, BSTR bstrName, BSTR bstrPassword, ULONG uchCaps)
  257. {
  258. DBGENTRY(CNmManagerObj::CreateConference);
  259. HRESULT hr = S_OK;
  260. if(m_bInitialized)
  261. {
  262. if(m_bNmActive)
  263. {
  264. if(ppConference)
  265. {
  266. if(m_spInternalNmManager)
  267. {
  268. switch(ConfPolicies::GetSecurityLevel())
  269. {
  270. case REQUIRED_POL_SECURITY:
  271. m_chCaps = uchCaps | NMCH_SECURE;
  272. break;
  273. case DISABLED_POL_SECURITY:
  274. m_chCaps = uchCaps & ~NMCH_SECURE;
  275. break;
  276. default:
  277. m_chCaps = uchCaps;
  278. break;
  279. }
  280. if(OfficeMode()) g_bOfficeModeSuspendNotifications = true;
  281. CComPtr<INmConference> spInternalINmConference;
  282. hr = m_spInternalNmManager->CreateConference(&spInternalINmConference, bstrName, bstrPassword, m_chCaps);
  283. if(SUCCEEDED(hr))
  284. {
  285. // This was created by the previous call
  286. *ppConference = GetSDKConferenceFromInternalConference(spInternalINmConference);
  287. if(*ppConference)
  288. {
  289. (*ppConference)->AddRef();
  290. }
  291. else
  292. {
  293. hr = E_UNEXPECTED;
  294. }
  295. }
  296. if(OfficeMode()) g_bOfficeModeSuspendNotifications = false;
  297. }
  298. else
  299. {
  300. hr = E_UNEXPECTED;
  301. }
  302. }
  303. else
  304. {
  305. hr = E_POINTER;
  306. }
  307. }
  308. else
  309. {
  310. hr = NM_E_NOT_ACTIVE;
  311. }
  312. }
  313. else
  314. {
  315. hr = NM_E_NOT_INITIALIZED;
  316. }
  317. DBGEXIT_HR(CNmManagerObj::CreateConference,hr);
  318. return hr;
  319. }
  320. STDMETHODIMP CNmManagerObj::EnumConference(IEnumNmConference **ppEnum)
  321. {
  322. DBGENTRY(CNmManagerObj::EnumConference);
  323. HRESULT hr = S_OK;
  324. if(m_bInitialized)
  325. {
  326. if(m_bNmActive)
  327. {
  328. hr = CreateEnumFromSimpleAryOfInterface<IEnumNmConference, INmConference>(m_SDKConferenceObjs, ppEnum);
  329. }
  330. else
  331. {
  332. hr = NM_E_NOT_ACTIVE;
  333. }
  334. }
  335. else
  336. {
  337. hr = NM_E_NOT_INITIALIZED;
  338. }
  339. DBGEXIT_HR(CNmManagerObj::EnumConference,hr);
  340. return hr;
  341. }
  342. STDMETHODIMP CNmManagerObj::CreateCall(INmCall **ppCall, NM_CALL_TYPE callType, NM_ADDR_TYPE addrType, BSTR bstrAddr, INmConference *pConference)
  343. {
  344. DBGENTRY(CNmManagerObj::CreateCall);
  345. HRESULT hr = S_OK;
  346. if(!m_bInitialized)
  347. {
  348. hr = NM_E_NOT_INITIALIZED;
  349. goto end;
  350. }
  351. if(!m_bNmActive)
  352. {
  353. hr = NM_E_NOT_ACTIVE;
  354. goto end;
  355. }
  356. if(m_spInternalNmManager)
  357. {
  358. if(!pConference)
  359. { // Get the active conference
  360. pConference = _GetActiveConference();
  361. if(!pConference)
  362. { // There is no active conf, so create a new one
  363. CComPtr<INmConference> spInternalINmConference;
  364. ULONG ulCaps = NMCH_AUDIO | NMCH_VIDEO | NMCH_DATA | NMCH_SHARE | NMCH_FT;
  365. LPTSTR szAddr = NULL;
  366. CCalltoParams params;
  367. bool bSecure = FALSE;
  368. if(SUCCEEDED(BSTR_to_LPTSTR(&szAddr, bstrAddr)))
  369. {
  370. ASSERT(NULL != szAddr);
  371. params.SetParams(szAddr);
  372. bSecure = params.GetBooleanParam(TEXT("secure"), bSecure);
  373. if(ConfPolicies::OutgoingSecurityPreferred() || bSecure)
  374. {
  375. ulCaps |= NMCH_SECURE;
  376. }
  377. delete [] szAddr;
  378. }
  379. hr = m_spInternalNmManager->CreateConference(&spInternalINmConference, NULL, NULL, ulCaps);
  380. if(SUCCEEDED(hr))
  381. {
  382. // the above call to CreateConference generates a callback, so we have this object now!
  383. pConference = GetSDKConferenceFromInternalConference(spInternalINmConference);
  384. }
  385. }
  386. }
  387. CComPtr<INmCall> spInternalINmCall;
  388. if(SUCCEEDED(hr))
  389. {
  390. if(addrType == NM_ADDR_CALLTO)
  391. {
  392. ASSERT( g_pCCallto != NULL );
  393. if(NM_CALL_DEFAULT == callType)
  394. {
  395. USES_CONVERSION;
  396. hr = g_pCCallto->Callto( OLE2T( bstrAddr ), // pointer to the callto url to try to place the call with...
  397. NULL, // pointer to the display name to use...
  398. NM_ADDR_CALLTO, // callto type to resolve this callto as...
  399. false, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
  400. NULL, // security preference, NULL for none. must be "compatible" with secure param if present...
  401. false, // whether or not save in mru...
  402. false, // whether or not to perform user interaction on errors...
  403. NULL, // if bUIEnabled is true this is the window to parent error/status windows to...
  404. &spInternalINmCall ); // out pointer to INmCall * to receive INmCall * generated by placing call...
  405. }
  406. else
  407. {
  408. hr = E_INVALIDARG;
  409. goto end;
  410. }
  411. }
  412. else
  413. {
  414. hr = SdkPlaceCall(callType, addrType, bstrAddr, NULL, NULL, &spInternalINmCall);
  415. }
  416. if(SUCCEEDED(hr))
  417. {
  418. CallCreated(spInternalINmCall);
  419. if(ppCall)
  420. {
  421. *ppCall = GetSDKCallFromInternalCall(spInternalINmCall);
  422. if(*ppCall)
  423. {
  424. (*ppCall)->AddRef();
  425. }
  426. }
  427. }
  428. }
  429. }
  430. else
  431. {
  432. hr = E_UNEXPECTED;
  433. ERROR_OUT(("Why don't we have a manager object"));
  434. }
  435. end:
  436. DBGEXIT_HR(CNmManagerObj::CreateCall,hr);
  437. return hr;
  438. }
  439. STDMETHODIMP CNmManagerObj::CallConference(INmCall **ppCall, NM_CALL_TYPE callType, NM_ADDR_TYPE addrType, BSTR bstrAddr, BSTR bstrConferenceName, BSTR bstrPassword)
  440. {
  441. DBGENTRY(CNmManagerObj::CallConference);
  442. HRESULT hr = S_OK;
  443. if(!m_bInitialized)
  444. {
  445. hr = NM_E_NOT_INITIALIZED;
  446. goto end;
  447. }
  448. if(!m_bNmActive)
  449. {
  450. hr = NM_E_NOT_ACTIVE;
  451. goto end;
  452. }
  453. {
  454. CComPtr<INmCall> spInternalINmCall;
  455. hr = SdkPlaceCall(callType, addrType, bstrAddr, bstrConferenceName, bstrPassword, &spInternalINmCall);
  456. if(SUCCEEDED(hr))
  457. {
  458. CallCreated(spInternalINmCall);
  459. *ppCall = GetSDKCallFromInternalCall(spInternalINmCall);
  460. if(*ppCall)
  461. {
  462. (*ppCall)->AddRef();
  463. }
  464. }
  465. }
  466. end:
  467. DBGEXIT_HR(CNmManagerObj::CallConference,hr);
  468. return hr;
  469. }
  470. STDMETHODIMP CNmManagerObj::EnumCall(IEnumNmCall **ppEnum)
  471. {
  472. DBGENTRY(CNmManagerObj::EnumCall);
  473. HRESULT hr = S_OK;
  474. if(m_bInitialized)
  475. {
  476. if(m_bNmActive)
  477. {
  478. hr = CreateEnumFromSimpleAryOfInterface<IEnumNmCall, INmCall>(m_SDKCallObjs, ppEnum);
  479. }
  480. else
  481. {
  482. hr = NM_E_NOT_ACTIVE;
  483. }
  484. }
  485. else
  486. {
  487. hr = NM_E_NOT_INITIALIZED;
  488. }
  489. DBGEXIT_HR(CNmManagerObj::EnumCall,hr);
  490. return hr;
  491. }
  492. ///////////////////////////////////////////////
  493. // INmObject methods
  494. ///////////////////////////////////////////////
  495. STDMETHODIMP CNmManagerObj::CallDialog(long hwnd, int cdOptions)
  496. {
  497. DBGENTRY(CNmManagerObj::CallDialog);
  498. HRESULT hr = S_OK;
  499. CFindSomeone::findSomeone(GetConfRoom());
  500. g_bSDKPostNotifications = true;
  501. if(OfficeMode() && !m_bSentConferenceCreated)
  502. {
  503. Fire_ConferenceCreated(m_SDKConferenceObjs[0]);
  504. }
  505. g_bSDKPostNotifications = false;
  506. DBGEXIT_HR(CNmManagerObj::CallDialog,hr);
  507. return hr;
  508. }
  509. extern "C" { BOOL WINAPI StartStopOldWB(LPCTSTR lpsz); }
  510. STDMETHODIMP CNmManagerObj::ShowLocal(NM_APPID id)
  511. {
  512. if(!m_bInitialized)
  513. {
  514. return NM_E_NOT_INITIALIZED;
  515. }
  516. if(!m_bNmActive)
  517. {
  518. return NM_E_NOT_ACTIVE;
  519. }
  520. switch (id)
  521. {
  522. case NM_APPID_WHITEBOARD:
  523. StartStopOldWB(NULL);
  524. return S_OK;
  525. case NM_APPID_T126_WHITEBOARD:
  526. return (T120_NO_ERROR == ::T120_LoadApplet(APPLET_ID_WB, TRUE , 0, FALSE, NULL)) ? S_OK : E_FAIL;
  527. case NM_APPID_CHAT:
  528. return (T120_NO_ERROR == T120_LoadApplet(APPLET_ID_CHAT, TRUE , 0, FALSE, NULL)) ? S_OK : E_FAIL;
  529. case NM_APPID_FILE_TRANSFER:
  530. return CFt::ShowFtUI();
  531. case NM_APPID_APPSHARING:
  532. if(g_pConfRoom && g_pConfRoom->IsSharingAllowed())
  533. {
  534. g_pConfRoom->CmdShowSharing();
  535. return S_OK;
  536. }
  537. return NM_E_SHARING_NOT_AVAILABLE;
  538. default:
  539. ERROR_OUT(("Unknown flag passed to ShowLocal"));
  540. break;
  541. }
  542. return E_INVALIDARG;
  543. }
  544. STDMETHODIMP CNmManagerObj::VerifyUserInfo(UINT_PTR hwnd, NM_VUI options)
  545. {
  546. ASSERT(0);
  547. return E_UNEXPECTED;
  548. }
  549. ////////////////////////////////////////////////////////////
  550. // IInternalConfExe
  551. ////////////////////////////////////////////////////////////
  552. STDMETHODIMP CNmManagerObj::LoggedIn()
  553. {
  554. DBGENTRY(STDMETHODIMP CNmManagerObj::LoggedIn);
  555. HRESULT hr = g_fLoggedOn ? S_OK : S_FALSE;
  556. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::LoggedIn,hr);
  557. return hr;
  558. }
  559. STDMETHODIMP CNmManagerObj::IsRunning()
  560. {
  561. DBGENTRY(STDMETHODIMP CNmManagerObj::IsRunning);
  562. HRESULT hr = g_pInternalNmManager ? S_OK : S_FALSE;
  563. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::IsRunning,hr);
  564. return hr;
  565. }
  566. STDMETHODIMP CNmManagerObj::InConference()
  567. {
  568. DBGENTRY(STDMETHODIMP CNmManagerObj::InConference);
  569. HRESULT hr = ::FIsConferenceActive() ? S_OK : S_FALSE;
  570. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::InConference,hr);
  571. return hr;
  572. }
  573. STDMETHODIMP CNmManagerObj::LDAPLogon(BOOL bLogon)
  574. {
  575. DBGENTRY(STDMETHODIMP CNmManagerObj::LDAPLogon);
  576. HRESULT hr = S_OK;
  577. if(g_pLDAP)
  578. {
  579. hr = bLogon ? g_pLDAP->LogonAsync() : g_pLDAP->Logoff();
  580. }
  581. else
  582. {
  583. hr = E_FAIL;
  584. }
  585. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::LDAPLogon,hr);
  586. return hr;
  587. }
  588. STDMETHODIMP CNmManagerObj::GetLocalCaps(DWORD* pdwLocalCaps)
  589. {
  590. DBGENTRY(STDMETHODIMP CNmManagerObj::);
  591. HRESULT hr = S_OK;
  592. *pdwLocalCaps = g_uMediaCaps;
  593. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::,hr);
  594. return hr;
  595. }
  596. STDMETHODIMP CNmManagerObj::IsNetMeetingRunning()
  597. {
  598. return g_pInternalNmManager ? S_OK : S_FALSE;
  599. }
  600. STDMETHODIMP CNmManagerObj::GetActiveConference(INmConference** ppConf)
  601. {
  602. if(ppConf && ms_pManagerObjList && m_dwSysInfoID)
  603. {
  604. for(int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  605. {
  606. if((*ms_pManagerObjList)[i]->m_dwID == m_dwSysInfoID)
  607. {
  608. if((*ms_pManagerObjList)[i]->m_SDKConferenceObjs.GetSize() != 0)
  609. {
  610. *ppConf = (*ms_pManagerObjList)[i]->m_SDKConferenceObjs[0];
  611. (*ppConf)->AddRef();
  612. return S_OK;
  613. }
  614. }
  615. }
  616. }
  617. return E_FAIL;
  618. }
  619. //--------------------------------------------------------------------------//
  620. // CNmManagerObj::ShellCalltoProtocolHandler. //
  621. //--------------------------------------------------------------------------//
  622. STDMETHODIMP
  623. CNmManagerObj::ShellCalltoProtocolHandler
  624. (
  625. BSTR url,
  626. BOOL bStrict
  627. ){
  628. ASSERT( g_pCCallto != NULL );
  629. HRESULT result = S_OK;
  630. if(!g_pInternalNmManager)
  631. {
  632. if(!CheckRemoteControlService())
  633. {
  634. return E_FAIL;
  635. }
  636. result = InitConfExe();
  637. }
  638. if( SUCCEEDED( result ) )
  639. {
  640. USES_CONVERSION;
  641. TCHAR *pszURL = OLE2T(url);
  642. if(CCallto::DoUserValidation(pszURL))
  643. {
  644. result = g_pCCallto->Callto( pszURL, // pointer to the callto url to try to place the call with...
  645. NULL, // pointer to the display name to use...
  646. NM_ADDR_CALLTO, // callto type to resolve this callto as...
  647. false, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
  648. NULL, // security preference, NULL for none. must be "compatible" with secure param if present...
  649. false, // whether or not save in mru...
  650. true, // whether or not to perform user interaction on errors...
  651. NULL, // if bUIEnabled is true this is the window to parent error/status windows to...
  652. NULL ); // out pointer to INmCall * to receive INmCall * generated by placing call...
  653. }
  654. }
  655. return( result );
  656. } // End of CNmManagerObj::ShellCalltoProtocolHandler.
  657. //--------------------------------------------------------------------------//
  658. // CNmManagerObj::Launch. //
  659. //--------------------------------------------------------------------------//
  660. STDMETHODIMP
  661. CNmManagerObj::Launch()
  662. {
  663. if(_Module.InitControlMode())
  664. {
  665. return E_FAIL;
  666. }
  667. else
  668. {
  669. if(!g_pInternalNmManager)
  670. {
  671. if(!CheckRemoteControlService())
  672. {
  673. return E_FAIL;
  674. }
  675. InitConfExe();
  676. }
  677. else
  678. {
  679. ::CreateConfRoomWindow();
  680. }
  681. }
  682. return S_OK;
  683. } // End of CNmManagerObj::Launch.
  684. LPTSTR StripDoubleQuotes(LPTSTR sz)
  685. {
  686. BOOL fSkippedQuote = FALSE;
  687. if (sz)
  688. {
  689. int cchLength;
  690. // Skip past first quote
  691. if (fSkippedQuote = (*sz == '"'))
  692. sz++;
  693. cchLength = lstrlen(sz);
  694. //
  695. // NOTE:
  696. // There may be DBCS implications with this. Hence we check to see
  697. // if we skipped the first quote; we assume that if the file name
  698. // starts with a quote it must end with one also. But we need to check
  699. // it out.
  700. //
  701. // Strip last quote
  702. if (fSkippedQuote && (cchLength > 0) && (sz[cchLength - 1] == '"'))
  703. {
  704. BYTE * pLastQuote = (BYTE *)&sz[cchLength - 1];
  705. *pLastQuote = '\0';
  706. }
  707. }
  708. return sz;
  709. }
  710. STDMETHODIMP CNmManagerObj::LaunchApplet(NM_APPID appid, BSTR strCmdLine)
  711. {
  712. USES_CONVERSION;
  713. if(!g_pInternalNmManager)
  714. {
  715. if(!CheckRemoteControlService())
  716. {
  717. return E_FAIL;
  718. }
  719. InitConfExe();
  720. }
  721. switch(appid)
  722. {
  723. case NM_APPID_WHITEBOARD:
  724. CmdShowOldWhiteboard(strCmdLine ? StripDoubleQuotes(OLE2T(strCmdLine)) : NULL);
  725. break;
  726. case NM_APPID_T126_WHITEBOARD:
  727. ::CmdShowNewWhiteboard(strCmdLine ? StripDoubleQuotes(OLE2T(strCmdLine)) : NULL);
  728. break;
  729. case NM_APPID_CHAT:
  730. CmdShowChat();
  731. break;
  732. }
  733. return S_OK;
  734. }
  735. STDMETHODIMP CNmManagerObj::GetUserData(REFGUID rguid, BYTE **ppb, ULONG *pcb)
  736. {
  737. if(g_pNmSysInfo)
  738. {
  739. return g_pNmSysInfo->GetUserData(rguid, ppb, pcb);
  740. }
  741. return NM_E_NOT_ACTIVE;
  742. }
  743. STDMETHODIMP CNmManagerObj::SetUserData(REFGUID rguid, BYTE *pb, ULONG cb)
  744. {
  745. //
  746. // Special case this guid to allow changing cert via SetUserData
  747. //
  748. if ( g_csguidSecurity == rguid )
  749. {
  750. return SetCertFromCertInfo ( (PCERT_INFO) pb );
  751. }
  752. if(g_pNmSysInfo)
  753. {
  754. return g_pNmSysInfo->SetUserData(rguid, pb, cb);
  755. }
  756. return NM_E_NOT_ACTIVE;
  757. }
  758. STDMETHODIMP CNmManagerObj::DisableH323(BOOL bDisableH323)
  759. {
  760. if(!g_pInternalNmManager)
  761. {
  762. _Module.SetSDKDisableH323(bDisableH323);
  763. return S_OK;
  764. }
  765. return NM_E_ALREADY_RUNNING;
  766. }
  767. STDMETHODIMP CNmManagerObj::SetCallerIsRTC (BOOL bCallerIsRTC)
  768. {
  769. if(!g_pInternalNmManager)
  770. {
  771. _Module.SetSDKCallerIsRTC(bCallerIsRTC);
  772. return S_OK;
  773. }
  774. return NM_E_ALREADY_RUNNING;
  775. }
  776. STDMETHODIMP CNmManagerObj::DisableInitialILSLogon(BOOL bDisable)
  777. {
  778. if(!g_pInternalNmManager)
  779. {
  780. _Module.SetSDKDisableInitialILSLogon(bDisable);
  781. return S_OK;
  782. }
  783. return NM_E_ALREADY_RUNNING;
  784. }
  785. ///////////////////////////////////////////////
  786. // INmManagerNotify methods:
  787. ///////////////////////////////////////////////
  788. STDMETHODIMP CNmManagerObj::NmUI(CONFN uNotify)
  789. {
  790. DBGENTRY(CNmManagerObj::NmUI);
  791. HRESULT hr = S_OK;
  792. // We should not be sending other notifactions
  793. ASSERT(CONFN_NM_STARTED == uNotify);
  794. hr = Fire_NmUI(uNotify);
  795. DBGEXIT_HR(CNmManagerObj::NmUI,hr);
  796. return hr;
  797. }
  798. STDMETHODIMP CNmManagerObj::ConferenceCreated(INmConference *pInternalConference)
  799. {
  800. DBGENTRY(CNmManagerOebj::ConferenceCreated);
  801. HRESULT hr = S_OK;
  802. CComPtr<INmConference> spConf;
  803. hr = CNmConferenceObj::CreateInstance(this, pInternalConference, &spConf);
  804. if(SUCCEEDED(hr))
  805. {
  806. spConf.p->AddRef();
  807. m_SDKConferenceObjs.Add(spConf.p);
  808. Fire_ConferenceCreated(spConf);
  809. if(!CFt::IsFtActive() && FileTransferNotifications())
  810. {
  811. CFt::StartNewConferenceSession();
  812. }
  813. }
  814. DBGEXIT_HR(CNmManagerObj::ConferenceCreated,hr);
  815. return hr;
  816. }
  817. STDMETHODIMP CNmManagerObj::CallCreated(INmCall *pInternalCall)
  818. {
  819. DBGENTRY(CNmManagerObj::CallCreated);
  820. HRESULT hr = S_OK;
  821. if(m_bInitialized)
  822. {
  823. if(NULL == GetSDKCallFromInternalCall(pInternalCall))
  824. {
  825. // First we make sure that we don't have the call object yet
  826. CComPtr<INmCall> spCall;
  827. hr = CNmCallObj::CreateInstance(this, pInternalCall, &spCall);
  828. if(SUCCEEDED(hr))
  829. {
  830. spCall.p->AddRef();
  831. m_SDKCallObjs.Add(spCall.p);
  832. Fire_CallCreated(spCall);
  833. }
  834. }
  835. }
  836. DBGEXIT_HR(CNmManagerObj::CallCreated,hr);
  837. return hr;
  838. }
  839. ///////////////////////////////////////////////
  840. // Notifications
  841. ///////////////////////////////////////////////
  842. HRESULT CNmManagerObj::Fire_ConferenceCreated(INmConference *pConference)
  843. {
  844. DBGENTRY(CNmManagerObj::Fire_ConferenceCreated);
  845. HRESULT hr = S_OK;
  846. // Som SDK clients need this to come in at a specific time....
  847. if(m_bSentConferenceCreated || OfficeMode() && g_bOfficeModeSuspendNotifications)
  848. {
  849. // We don't have to notify anyone at all...
  850. return S_OK;
  851. }
  852. if(!g_bSDKPostNotifications)
  853. {
  854. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  855. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  856. {
  857. m_bSentConferenceCreated = true;
  858. INmManagerNotify* pNotify = reinterpret_cast<INmManagerNotify*>(pCP->m_vec.GetAt(i));
  859. if(pNotify)
  860. {
  861. pNotify->ConferenceCreated(pConference);
  862. // Sinc up the channels, etc.
  863. com_cast<IInternalConferenceObj>(pConference)->FireNotificationsToSyncToInternalObject();
  864. }
  865. }
  866. }
  867. else
  868. {
  869. hr = CSDKWindow::PostConferenceCreated(this, pConference);
  870. }
  871. DBGEXIT_HR(CNmManagerObj::Fire_ConferenceCreated,hr);
  872. return hr;
  873. }
  874. HRESULT CNmManagerObj::Fire_CallCreated(INmCall* pCall)
  875. {
  876. DBGENTRY(CNmManagerObj::Fire_CallCreated);
  877. HRESULT hr = S_OK;
  878. // Always send Outgoing call notifications
  879. // Only send incoming call notifications to INIT CONTROL clients.
  880. if((S_OK != pCall->IsIncoming()) || _Module.InitControlMode())
  881. {
  882. if(!g_bSDKPostNotifications)
  883. {
  884. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  885. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  886. {
  887. INmManagerNotify* pNotify = reinterpret_cast<INmManagerNotify*>(pCP->m_vec.GetAt(i));
  888. if(pNotify)
  889. {
  890. pNotify->CallCreated(pCall);
  891. }
  892. }
  893. }
  894. else
  895. {
  896. hr = CSDKWindow::PostCallCreated(this, pCall);
  897. }
  898. }
  899. DBGEXIT_HR(CNmManagerObj::Fire_CallCreated,hr);
  900. return hr;
  901. }
  902. HRESULT CNmManagerObj::Fire_NmUI(CONFN uNotify)
  903. {
  904. DBGENTRY(CNmManagerObj::Fire_NmUI);
  905. HRESULT hr = S_OK;
  906. // notice the InSendMessage statement.
  907. // The problem is that we can get this notificaiton in
  908. // response to the taskbar icon being clicked. In that case
  909. // an inter-thread SendMessage is occuring. If we try to make
  910. // the NmUi call, we will get RPC_E_CANTCALLOUT_INPUTSYNCCALL
  911. if(!g_bSDKPostNotifications && !InSendMessage())
  912. {
  913. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  914. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  915. {
  916. INmManagerNotify* pNotify = reinterpret_cast<INmManagerNotify*>(pCP->m_vec.GetAt(i));
  917. if(pNotify)
  918. {
  919. pNotify->NmUI(uNotify);
  920. }
  921. }
  922. }
  923. else
  924. {
  925. hr = CSDKWindow::PostManagerNmUI(this, uNotify);
  926. }
  927. DBGEXIT_HR(CNmManagerObj::Fire_NmUI,hr);
  928. return hr;
  929. }
  930. ///////////////////////////////////////////////
  931. // Helper Fns
  932. ///////////////////////////////////////////////
  933. INmConference* CNmManagerObj::_GetActiveConference()
  934. {
  935. INmConference* pConf = NULL;
  936. if(m_SDKConferenceObjs.GetSize())
  937. {
  938. pConf = m_SDKConferenceObjs[0];
  939. }
  940. return pConf;
  941. }
  942. INmCall* CNmManagerObj::GetSDKCallFromInternalCall(INmCall* pInternalCall)
  943. {
  944. INmCall* pRet = NULL;
  945. for( int i = 0; i < m_SDKCallObjs.GetSize(); ++i)
  946. {
  947. CComQIPtr<IInternalCallObj> spInternal = m_SDKCallObjs[i];
  948. ASSERT(spInternal);
  949. CComPtr<INmCall> spCall;
  950. if(SUCCEEDED(spInternal->GetInternalINmCall(&spCall)))
  951. {
  952. if(spCall.IsEqualObject(pInternalCall))
  953. {
  954. pRet = m_SDKCallObjs[i];
  955. break;
  956. }
  957. }
  958. }
  959. return pRet;
  960. }
  961. INmConference* CNmManagerObj::GetSDKConferenceFromInternalConference(INmConference* pInternalConference)
  962. {
  963. INmConference* pRet = NULL;
  964. for( int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  965. {
  966. CComQIPtr<IInternalConferenceObj> spInternal = m_SDKConferenceObjs[i];
  967. ASSERT(spInternal);
  968. CComPtr<INmConference> spConference;
  969. if(SUCCEEDED(spInternal->GetInternalINmConference(&spConference)))
  970. {
  971. if(spConference.IsEqualObject(pInternalConference))
  972. {
  973. pRet = m_SDKConferenceObjs[i];
  974. break;
  975. }
  976. }
  977. }
  978. return pRet;
  979. }
  980. HRESULT CNmManagerObj::RemoveCall(INmCall* pSDKCallObj)
  981. {
  982. HRESULT hr = S_OK;
  983. for(int i = 0; i < m_SDKCallObjs.GetSize(); ++i)
  984. {
  985. CComPtr<INmCall> spSDKCallObj = m_SDKCallObjs[i];
  986. if(spSDKCallObj.IsEqualObject(pSDKCallObj))
  987. {
  988. m_SDKCallObjs.RemoveAt(i);
  989. spSDKCallObj.p->Release();
  990. }
  991. }
  992. return hr;
  993. }
  994. HRESULT CNmManagerObj::RemoveConference(INmConference* pSDKConferenceObj)
  995. {
  996. HRESULT hr = S_OK;
  997. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  998. {
  999. CComPtr<INmConference> spSDKConferenceObj = m_SDKConferenceObjs[i];
  1000. if(spSDKConferenceObj.IsEqualObject(pSDKConferenceObj))
  1001. {
  1002. m_SDKConferenceObjs.RemoveAt(i);
  1003. spSDKConferenceObj.p->Release();
  1004. }
  1005. }
  1006. return hr;
  1007. }
  1008. bool CNmManagerObj::AudioNotifications()
  1009. {
  1010. return m_bInitialized && (m_chCaps & NMCH_AUDIO);
  1011. }
  1012. bool CNmManagerObj::VideoNotifications()
  1013. {
  1014. return m_bInitialized && (m_chCaps & NMCH_VIDEO);
  1015. }
  1016. bool CNmManagerObj::DataNotifications()
  1017. {
  1018. return m_bInitialized && (m_chCaps & NMCH_DATA);
  1019. }
  1020. bool CNmManagerObj::FileTransferNotifications()
  1021. {
  1022. return m_bInitialized && (m_chCaps & NMCH_FT);
  1023. }
  1024. bool CNmManagerObj::AppSharingNotifications()
  1025. {
  1026. return m_bInitialized && (m_chCaps & NMCH_SHARE);
  1027. }
  1028. //static
  1029. void CNmManagerObj::NetMeetingLaunched()
  1030. {
  1031. ASSERT(ms_pManagerObjList);
  1032. if(ms_pManagerObjList)
  1033. {
  1034. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1035. {
  1036. (*ms_pManagerObjList)[i]->Fire_NmUI(CONFN_NM_STARTED);
  1037. }
  1038. }
  1039. }
  1040. //static
  1041. void CNmManagerObj::SharableAppStateChanged(HWND hWnd, NM_SHAPP_STATE state)
  1042. {
  1043. if(ms_pManagerObjList)
  1044. {
  1045. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1046. {
  1047. (*ms_pManagerObjList)[i]->_SharableAppStateChanged(hWnd, state);
  1048. }
  1049. }
  1050. }
  1051. void CNmManagerObj::_SharableAppStateChanged(HWND hWnd, NM_SHAPP_STATE state)
  1052. {
  1053. // Free our conferencing objects
  1054. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1055. {
  1056. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->SharableAppStateChanged(hWnd, state);
  1057. }
  1058. }
  1059. //static
  1060. void CNmManagerObj::AppSharingChannelChanged()
  1061. {
  1062. if(ms_pManagerObjList)
  1063. {
  1064. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1065. {
  1066. (*ms_pManagerObjList)[i]->_AppSharingChannelChanged();
  1067. }
  1068. }
  1069. }
  1070. void CNmManagerObj::_AppSharingChannelChanged()
  1071. {
  1072. // Free our conferencing objects
  1073. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1074. {
  1075. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->AppSharingChannelChanged();
  1076. }
  1077. }
  1078. //static
  1079. void CNmManagerObj::AppSharingChannelActiveStateChanged(bool bActive)
  1080. {
  1081. if(ms_pManagerObjList)
  1082. {
  1083. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1084. {
  1085. (*ms_pManagerObjList)[i]->_AppSharingChannelActiveStateChanged(bActive);
  1086. }
  1087. }
  1088. }
  1089. void CNmManagerObj::_AppSharingChannelActiveStateChanged(bool bActive)
  1090. {
  1091. // Free our conferencing objects
  1092. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1093. {
  1094. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->AppSharingStateChanged(bActive);
  1095. }
  1096. }
  1097. //static
  1098. void CNmManagerObj::ASLocalMemberChanged()
  1099. {
  1100. if(ms_pManagerObjList)
  1101. {
  1102. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1103. {
  1104. (*ms_pManagerObjList)[i]->_ASLocalMemberChanged();
  1105. }
  1106. }
  1107. }
  1108. void CNmManagerObj::_ASLocalMemberChanged()
  1109. {
  1110. // notify our conferencing objects
  1111. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1112. {
  1113. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->ASLocalMemberChanged();
  1114. }
  1115. }
  1116. //static
  1117. void CNmManagerObj::ASMemberChanged(UINT gccID)
  1118. {
  1119. if(ms_pManagerObjList)
  1120. {
  1121. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1122. {
  1123. (*ms_pManagerObjList)[i]->_ASMemberChanged(gccID);
  1124. }
  1125. }
  1126. }
  1127. void CNmManagerObj::_ASMemberChanged(UINT gccID)
  1128. {
  1129. // notify our conferencing objects
  1130. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1131. {
  1132. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->ASMemberChanged(gccID);
  1133. }
  1134. }
  1135. // static
  1136. void CNmManagerObj::AudioChannelActiveState(BOOL bActive, BOOL bIsIncoming)
  1137. {
  1138. if(ms_pManagerObjList)
  1139. {
  1140. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1141. {
  1142. (*ms_pManagerObjList)[i]->_AudioChannelActiveState(bActive, bIsIncoming);
  1143. }
  1144. }
  1145. }
  1146. void CNmManagerObj::_AudioChannelActiveState(BOOL bActive, BOOL bIsIncoming)
  1147. {
  1148. // notify our conferencing objects
  1149. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1150. {
  1151. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->AudioChannelActiveState(bActive ? TRUE : FALSE, bIsIncoming);
  1152. }
  1153. }
  1154. // static
  1155. void CNmManagerObj::VideoChannelActiveState(BOOL bActive, BOOL bIsIncoming)
  1156. {
  1157. if(ms_pManagerObjList)
  1158. {
  1159. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1160. {
  1161. (*ms_pManagerObjList)[i]->_VideoChannelActiveState(bActive, bIsIncoming);
  1162. }
  1163. }
  1164. }
  1165. void CNmManagerObj::_VideoChannelActiveState(BOOL bActive, BOOL bIsIncoming)
  1166. {
  1167. // notify our conferencing objects
  1168. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1169. {
  1170. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->VideoChannelActiveState(bActive ? TRUE : FALSE, bIsIncoming);
  1171. }
  1172. }
  1173. // static
  1174. void CNmManagerObj::VideoPropChanged(DWORD dwProp, BOOL bIsIncoming)
  1175. {
  1176. if(ms_pManagerObjList)
  1177. {
  1178. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1179. {
  1180. (*ms_pManagerObjList)[i]->_VideoPropChanged(dwProp, bIsIncoming);
  1181. }
  1182. }
  1183. }
  1184. void CNmManagerObj::_VideoPropChanged(DWORD dwProp, BOOL bIsIncoming)
  1185. {
  1186. // notify our conferencing objects
  1187. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1188. {
  1189. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->VideoChannelPropChanged(dwProp, bIsIncoming);
  1190. }
  1191. }
  1192. // static
  1193. void CNmManagerObj::VideoChannelStateChanged(NM_VIDEO_STATE uState, BOOL bIsIncoming)
  1194. {
  1195. if(ms_pManagerObjList)
  1196. {
  1197. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1198. {
  1199. (*ms_pManagerObjList)[i]->_VideoChannelStateChanged(uState, bIsIncoming);
  1200. }
  1201. }
  1202. }
  1203. void CNmManagerObj::_VideoChannelStateChanged(NM_VIDEO_STATE uState, BOOL bIsIncoming)
  1204. {
  1205. // notify our conferencing objects
  1206. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1207. {
  1208. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->VideoChannelStateChanged(uState, bIsIncoming);
  1209. }
  1210. }
  1211. UINT CNmManagerObj::GetManagerCount(ULONG uOption)
  1212. {
  1213. UINT nMgrs = 0;
  1214. for(int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1215. {
  1216. if(uOption == (*ms_pManagerObjList)[i]->m_uOptions)
  1217. {
  1218. nMgrs++;
  1219. }
  1220. }
  1221. return nMgrs;
  1222. }
  1223. void CNmManagerObj::OnShowUI(BOOL fShow)
  1224. {
  1225. _Module.SetUIVisible(fShow);
  1226. if (fShow)
  1227. {
  1228. CConfMan::AllowAV(TRUE);
  1229. }
  1230. else
  1231. {
  1232. if(0 != GetManagerCount(NM_INIT_OBJECT))
  1233. {
  1234. CConfMan::AllowAV(FALSE);
  1235. }
  1236. }
  1237. }
  1238. HRESULT CNmManagerObj::SdkPlaceCall(NM_CALL_TYPE callType,
  1239. NM_ADDR_TYPE addrType,
  1240. BSTR bstrAddr,
  1241. BSTR bstrConf,
  1242. BSTR bstrPw,
  1243. INmCall **ppInternalCall)
  1244. {
  1245. USES_CONVERSION;
  1246. HRESULT hr;
  1247. DWORD dwFlags = MapNmCallTypeToCallFlags(callType, addrType, g_uMediaCaps);
  1248. if (0 == dwFlags)
  1249. {
  1250. hr = NM_CALLERR_MEDIA;
  1251. goto end;
  1252. }
  1253. {
  1254. if(NM_ADDR_T120_TRANSPORT == addrType)
  1255. {
  1256. //
  1257. // Check if "+secure=true" parameter was passed
  1258. //
  1259. LPTSTR szAddr = NULL;
  1260. CCalltoParams params;
  1261. bool bSecure = FALSE;
  1262. if(SUCCEEDED(BSTR_to_LPTSTR(&szAddr, bstrAddr)))
  1263. {
  1264. ASSERT(NULL != szAddr);
  1265. params.SetParams(szAddr);
  1266. bSecure = params.GetBooleanParam(TEXT("secure"), bSecure);
  1267. //
  1268. // Yes it was in the parameters.
  1269. // Now make sure to remove it
  1270. // The addre now is like "111.222.333.444+secure=true"
  1271. // The call will only work if we pass the ip address only
  1272. //
  1273. if(bSecure)
  1274. {
  1275. // Get the syze of the bstr
  1276. int cch = SysStringByteLen(bstrAddr);
  1277. BYTE *pByte = (BYTE *) bstrAddr;
  1278. for(int i = 0; i < cch;i++)
  1279. {
  1280. // Null terminate the string
  1281. if(*pByte == '+')
  1282. {
  1283. *pByte = '\0';
  1284. break;
  1285. }
  1286. pByte++;
  1287. }
  1288. dwFlags |= CRPCF_SECURE;
  1289. }
  1290. delete [] szAddr;
  1291. }
  1292. }
  1293. CCallResolver CallResolver(OLE2T(bstrAddr), addrType);
  1294. hr = CallResolver.Resolve();
  1295. if (FAILED(hr))
  1296. {
  1297. goto end;
  1298. }
  1299. CCall* pCall = new CCall(CallResolver.GetPszAddr(), OLE2T(bstrAddr), NM_ADDR_CALLTO, FALSE, FALSE);
  1300. if(NULL == pCall)
  1301. {
  1302. goto end;
  1303. }
  1304. pCall->AddRef();
  1305. switch(CallResolver.GetAddrType())
  1306. {
  1307. case NM_ADDR_ULS:
  1308. case NM_ADDR_IP:
  1309. case NM_ADDR_MACHINENAME:
  1310. case NM_ADDR_H323_GATEWAY:
  1311. ASSERT(FIpAddress(CallResolver.GetPszAddrIP()));
  1312. /////////////////////////////////////////////
  1313. // !!!!! HEY RYAN, WERE FALLING THROUGH !!!!!
  1314. /////////////////////////////////////////////
  1315. case NM_ADDR_T120_TRANSPORT:
  1316. hr = pCall->PlaceCall(
  1317. dwFlags, // dwFlags
  1318. CallResolver.GetAddrType(), // addrType
  1319. NULL, // szSetup
  1320. (NM_ADDR_T120_TRANSPORT == CallResolver.GetAddrType()) ?
  1321. CallResolver.GetPszAddr() :
  1322. CallResolver.GetPszAddrIP(), // szDestination
  1323. CallResolver.GetPszAddr(),// szAlias
  1324. NULL, // szURL
  1325. OLE2T(bstrConf), // szConference
  1326. OLE2T(bstrPw), // szPassword
  1327. NULL); // szUserData
  1328. break;
  1329. default:
  1330. ERROR_OUT(("Don't know this call type"));
  1331. ASSERT(0);
  1332. break;
  1333. }
  1334. if( FAILED(hr) && (pCall->GetState() == NM_CALL_INVALID ) )
  1335. {
  1336. // just release the call to free the data
  1337. // otherwise wait for the call state to be changed
  1338. pCall->Release();
  1339. }
  1340. if(ppInternalCall && SUCCEEDED(hr))
  1341. {
  1342. *ppInternalCall = pCall->GetINmCall();
  1343. (*ppInternalCall)->AddRef();
  1344. }
  1345. pCall->Release();
  1346. }
  1347. end:
  1348. if( FAILED( hr ) && _Module.IsUIActive() )
  1349. {
  1350. DisplayCallError( hr, OLE2T( bstrAddr ) );
  1351. }
  1352. return hr;
  1353. }
  1354. DWORD CNmManagerObj::MapNmCallTypeToCallFlags(NM_CALL_TYPE callType, NM_ADDR_TYPE addrType, UINT uCaps)
  1355. {
  1356. DWORD dwFlags = 0;
  1357. BOOL fForceSecure = FALSE;
  1358. // Check global conference status
  1359. if (INmConference *pConf = ::GetActiveConference())
  1360. {
  1361. // We are in a conference. Use the conference security setting.
  1362. DWORD dwCaps;
  1363. if ((S_OK == pConf->GetNmchCaps(&dwCaps)) &&
  1364. (NMCH_SECURE & dwCaps))
  1365. {
  1366. fForceSecure = TRUE;
  1367. }
  1368. }
  1369. else
  1370. {
  1371. fForceSecure = (REQUIRED_POL_SECURITY == ConfPolicies::GetSecurityLevel());
  1372. }
  1373. switch(addrType)
  1374. {
  1375. case NM_ADDR_T120_TRANSPORT:
  1376. dwFlags = CRPCF_T120 | CRPCF_DATA;
  1377. if(ConfPolicies::OutgoingSecurityPreferred() || fForceSecure)
  1378. {
  1379. dwFlags |= CRPCF_SECURE;
  1380. }
  1381. break;
  1382. default:
  1383. switch (callType)
  1384. {
  1385. case NM_CALL_T120:
  1386. if (fForceSecure)
  1387. {
  1388. dwFlags = CRPCF_T120 | CRPCF_DATA | CRPCF_SECURE;
  1389. }
  1390. else
  1391. {
  1392. dwFlags = CRPCF_T120 | CRPCF_DATA;
  1393. }
  1394. break;
  1395. case NM_CALL_H323:
  1396. if (!fForceSecure)
  1397. {
  1398. dwFlags = CRPCF_H323CC;
  1399. if (uCaps & (CAPFLAG_RECV_AUDIO | CAPFLAG_SEND_AUDIO))
  1400. dwFlags |= CRPCF_AUDIO;
  1401. if (uCaps & (CAPFLAG_RECV_VIDEO | CAPFLAG_SEND_VIDEO))
  1402. dwFlags |= CRPCF_VIDEO;
  1403. }
  1404. break;
  1405. case NM_CALL_DEFAULT:
  1406. if (fForceSecure)
  1407. {
  1408. dwFlags = CRPCF_T120 | CRPCF_DATA | CRPCF_SECURE;
  1409. }
  1410. else
  1411. {
  1412. dwFlags = CRPCF_DEFAULT;
  1413. // strip AV if policies prohibit
  1414. if((uCaps & (CAPFLAG_RECV_AUDIO |CAPFLAG_SEND_AUDIO)) == 0)
  1415. {
  1416. dwFlags &= ~CRPCF_AUDIO;
  1417. }
  1418. if((uCaps & (CAPFLAG_RECV_VIDEO |CAPFLAG_SEND_VIDEO)) == 0)
  1419. {
  1420. dwFlags &= ~CRPCF_VIDEO;
  1421. }
  1422. }
  1423. break;
  1424. default:
  1425. dwFlags = 0;
  1426. break;
  1427. }
  1428. }
  1429. return dwFlags;
  1430. }