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.

1778 lines
39 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. // TODO: What about NMCH_SECURE?
  365. ULONG ulCaps = NMCH_AUDIO | NMCH_VIDEO | NMCH_DATA | NMCH_SHARE | NMCH_FT;
  366. CCalltoParams params;
  367. bool bSecure = FALSE;
  368. LPTSTR szName;
  369. hr = BSTR_to_LPTSTR (&szName, bstrAddr);
  370. if (SUCCEEDED(hr))
  371. {
  372. params.SetParams(szName);
  373. bSecure = params.GetBooleanParam("secure",bSecure);
  374. delete (szName);
  375. }
  376. if(ConfPolicies::OutgoingSecurityPreferred() || bSecure)
  377. {
  378. ulCaps |= NMCH_SECURE;
  379. }
  380. hr = m_spInternalNmManager->CreateConference(&spInternalINmConference, NULL, NULL, ulCaps);
  381. if(SUCCEEDED(hr))
  382. {
  383. // the above call to CreateConference generates a callback, so we have this object now!
  384. pConference = GetSDKConferenceFromInternalConference(spInternalINmConference);
  385. }
  386. }
  387. }
  388. CComPtr<INmCall> spInternalINmCall;
  389. if(SUCCEEDED(hr))
  390. {
  391. if(addrType == NM_ADDR_CALLTO)
  392. {
  393. ASSERT( g_pCCallto != NULL );
  394. if(NM_CALL_DEFAULT == callType)
  395. {
  396. LPTSTR szName;
  397. hr = BSTR_to_LPTSTR (&szName, bstrAddr);
  398. if (SUCCEEDED(hr))
  399. {
  400. hr = g_pCCallto->Callto(szName, // pointer to the callto url to try to place the call with...
  401. NULL, // pointer to the display name to use...
  402. NM_ADDR_CALLTO, // callto type to resolve this callto as...
  403. false, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
  404. NULL, // security preference, NULL for none. must be "compatible" with secure param if present...
  405. false, // whether or not save in mru...
  406. false, // whether or not to perform user interaction on errors...
  407. NULL, // if bUIEnabled is true this is the window to parent error/status windows to...
  408. &spInternalINmCall ); // out pointer to INmCall * to receive INmCall * generated by placing call...
  409. delete (szName);
  410. }
  411. else
  412. {
  413. goto end;
  414. }
  415. }
  416. else
  417. {
  418. hr = E_INVALIDARG;
  419. goto end;
  420. }
  421. }
  422. else
  423. {
  424. hr = SdkPlaceCall(callType, addrType, bstrAddr, NULL, NULL, &spInternalINmCall);
  425. }
  426. if(SUCCEEDED(hr))
  427. {
  428. CallCreated(spInternalINmCall);
  429. if(ppCall)
  430. {
  431. *ppCall = GetSDKCallFromInternalCall(spInternalINmCall);
  432. if(*ppCall)
  433. {
  434. (*ppCall)->AddRef();
  435. }
  436. }
  437. }
  438. }
  439. }
  440. else
  441. {
  442. hr = E_UNEXPECTED;
  443. ERROR_OUT(("Why don't we have a manager object"));
  444. }
  445. end:
  446. DBGEXIT_HR(CNmManagerObj::CreateCall,hr);
  447. return hr;
  448. }
  449. STDMETHODIMP CNmManagerObj::CallConference(INmCall **ppCall, NM_CALL_TYPE callType, NM_ADDR_TYPE addrType, BSTR bstrAddr, BSTR bstrConferenceName, BSTR bstrPassword)
  450. {
  451. DBGENTRY(CNmManagerObj::CallConference);
  452. HRESULT hr = S_OK;
  453. if(!m_bInitialized)
  454. {
  455. hr = NM_E_NOT_INITIALIZED;
  456. goto end;
  457. }
  458. if(!m_bNmActive)
  459. {
  460. hr = NM_E_NOT_ACTIVE;
  461. goto end;
  462. }
  463. {
  464. CComPtr<INmCall> spInternalINmCall;
  465. hr = SdkPlaceCall(callType, addrType, bstrAddr, bstrConferenceName, bstrPassword, &spInternalINmCall);
  466. if(SUCCEEDED(hr))
  467. {
  468. CallCreated(spInternalINmCall);
  469. *ppCall = GetSDKCallFromInternalCall(spInternalINmCall);
  470. if(*ppCall)
  471. {
  472. (*ppCall)->AddRef();
  473. }
  474. }
  475. }
  476. end:
  477. DBGEXIT_HR(CNmManagerObj::CallConference,hr);
  478. return hr;
  479. }
  480. STDMETHODIMP CNmManagerObj::EnumCall(IEnumNmCall **ppEnum)
  481. {
  482. DBGENTRY(CNmManagerObj::EnumCall);
  483. HRESULT hr = S_OK;
  484. if(m_bInitialized)
  485. {
  486. if(m_bNmActive)
  487. {
  488. hr = CreateEnumFromSimpleAryOfInterface<IEnumNmCall, INmCall>(m_SDKCallObjs, ppEnum);
  489. }
  490. else
  491. {
  492. hr = NM_E_NOT_ACTIVE;
  493. }
  494. }
  495. else
  496. {
  497. hr = NM_E_NOT_INITIALIZED;
  498. }
  499. DBGEXIT_HR(CNmManagerObj::EnumCall,hr);
  500. return hr;
  501. }
  502. ///////////////////////////////////////////////
  503. // INmObject methods
  504. ///////////////////////////////////////////////
  505. STDMETHODIMP CNmManagerObj::CallDialog(long hwnd, int cdOptions)
  506. {
  507. DBGENTRY(CNmManagerObj::CallDialog);
  508. HRESULT hr = S_OK;
  509. CFindSomeone::findSomeone(GetConfRoom());
  510. g_bSDKPostNotifications = true;
  511. if(OfficeMode() && !m_bSentConferenceCreated)
  512. {
  513. Fire_ConferenceCreated(m_SDKConferenceObjs[0]);
  514. }
  515. g_bSDKPostNotifications = false;
  516. DBGEXIT_HR(CNmManagerObj::CallDialog,hr);
  517. return hr;
  518. }
  519. extern "C" { BOOL WINAPI StartStopOldWB(LPCTSTR lpsz); }
  520. STDMETHODIMP CNmManagerObj::ShowLocal(NM_APPID id)
  521. {
  522. if(!m_bInitialized)
  523. {
  524. return NM_E_NOT_INITIALIZED;
  525. }
  526. if(!m_bNmActive)
  527. {
  528. return NM_E_NOT_ACTIVE;
  529. }
  530. switch (id)
  531. {
  532. case NM_APPID_WHITEBOARD:
  533. StartStopOldWB(NULL);
  534. return S_OK;
  535. case NM_APPID_T126_WHITEBOARD:
  536. return (T120_NO_ERROR == ::T120_LoadApplet(APPLET_ID_WB, TRUE , 0, FALSE, NULL)) ? S_OK : E_FAIL;
  537. case NM_APPID_CHAT:
  538. return (T120_NO_ERROR == T120_LoadApplet(APPLET_ID_CHAT, TRUE , 0, FALSE, NULL)) ? S_OK : E_FAIL;
  539. case NM_APPID_FILE_TRANSFER:
  540. return CFt::ShowFtUI();
  541. case NM_APPID_APPSHARING:
  542. if(g_pConfRoom && g_pConfRoom->IsSharingAllowed())
  543. {
  544. g_pConfRoom->CmdShowSharing();
  545. return S_OK;
  546. }
  547. return NM_E_SHARING_NOT_AVAILABLE;
  548. default:
  549. ERROR_OUT(("Unknown flag passed to ShowLocal"));
  550. break;
  551. }
  552. return E_INVALIDARG;
  553. }
  554. STDMETHODIMP CNmManagerObj::VerifyUserInfo(UINT_PTR hwnd, NM_VUI options)
  555. {
  556. ASSERT(0);
  557. return E_UNEXPECTED;
  558. }
  559. ////////////////////////////////////////////////////////////
  560. // IInternalConfExe
  561. ////////////////////////////////////////////////////////////
  562. STDMETHODIMP CNmManagerObj::LoggedIn()
  563. {
  564. DBGENTRY(STDMETHODIMP CNmManagerObj::LoggedIn);
  565. HRESULT hr = g_fLoggedOn ? S_OK : S_FALSE;
  566. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::LoggedIn,hr);
  567. return hr;
  568. }
  569. STDMETHODIMP CNmManagerObj::IsRunning()
  570. {
  571. DBGENTRY(STDMETHODIMP CNmManagerObj::IsRunning);
  572. HRESULT hr = g_pInternalNmManager ? S_OK : S_FALSE;
  573. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::IsRunning,hr);
  574. return hr;
  575. }
  576. STDMETHODIMP CNmManagerObj::InConference()
  577. {
  578. DBGENTRY(STDMETHODIMP CNmManagerObj::InConference);
  579. HRESULT hr = ::FIsConferenceActive() ? S_OK : S_FALSE;
  580. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::InConference,hr);
  581. return hr;
  582. }
  583. STDMETHODIMP CNmManagerObj::LDAPLogon(BOOL bLogon)
  584. {
  585. DBGENTRY(STDMETHODIMP CNmManagerObj::LDAPLogon);
  586. HRESULT hr = S_OK;
  587. if(g_pLDAP)
  588. {
  589. hr = bLogon ? g_pLDAP->LogonAsync() : g_pLDAP->Logoff();
  590. }
  591. else
  592. {
  593. hr = E_FAIL;
  594. }
  595. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::LDAPLogon,hr);
  596. return hr;
  597. }
  598. STDMETHODIMP CNmManagerObj::GetLocalCaps(DWORD* pdwLocalCaps)
  599. {
  600. DBGENTRY(STDMETHODIMP CNmManagerObj::);
  601. HRESULT hr = S_OK;
  602. *pdwLocalCaps = g_uMediaCaps;
  603. DBGEXIT_HR(STDMETHODIMP CNmManagerObj::,hr);
  604. return hr;
  605. }
  606. STDMETHODIMP CNmManagerObj::IsNetMeetingRunning()
  607. {
  608. return g_pInternalNmManager ? S_OK : S_FALSE;
  609. }
  610. STDMETHODIMP CNmManagerObj::GetActiveConference(INmConference** ppConf)
  611. {
  612. if(ppConf && ms_pManagerObjList && m_dwSysInfoID)
  613. {
  614. for(int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  615. {
  616. if((*ms_pManagerObjList)[i]->m_dwID == m_dwSysInfoID)
  617. {
  618. if((*ms_pManagerObjList)[i]->m_SDKConferenceObjs.GetSize() != 0)
  619. {
  620. *ppConf = (*ms_pManagerObjList)[i]->m_SDKConferenceObjs[0];
  621. (*ppConf)->AddRef();
  622. return S_OK;
  623. }
  624. }
  625. }
  626. }
  627. return E_FAIL;
  628. }
  629. //--------------------------------------------------------------------------//
  630. // CNmManagerObj::ShellCalltoProtocolHandler. //
  631. //--------------------------------------------------------------------------//
  632. STDMETHODIMP
  633. CNmManagerObj::ShellCalltoProtocolHandler
  634. (
  635. BSTR url,
  636. BOOL bStrict
  637. ){
  638. ASSERT( g_pCCallto != NULL );
  639. HRESULT result = S_OK;
  640. if(!g_pInternalNmManager)
  641. {
  642. if(!CheckRemoteControlService())
  643. {
  644. return E_FAIL;
  645. }
  646. result = InitConfExe();
  647. }
  648. if( SUCCEEDED( result ) )
  649. {
  650. LPTSTR szName;
  651. result = BSTR_to_LPTSTR (&szName, url);
  652. if (SUCCEEDED(result))
  653. {
  654. if(CCallto::DoUserValidation(szName))
  655. {
  656. result = g_pCCallto->Callto(szName, // pointer to the callto url to try to place the call with...
  657. NULL, // pointer to the display name to use...
  658. NM_ADDR_CALLTO, // callto type to resolve this callto as...
  659. false, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
  660. NULL, // security preference, NULL for none. must be "compatible" with secure param if present...
  661. false, // whether or not save in mru...
  662. true, // whether or not to perform user interaction on errors...
  663. NULL, // if bUIEnabled is true this is the window to parent error/status windows to...
  664. NULL ); // out pointer to INmCall * to receive INmCall * generated by placing call...
  665. }
  666. delete (szName);
  667. }
  668. }
  669. return( result );
  670. } // End of CNmManagerObj::ShellCalltoProtocolHandler.
  671. //--------------------------------------------------------------------------//
  672. // CNmManagerObj::Launch. //
  673. //--------------------------------------------------------------------------//
  674. STDMETHODIMP
  675. CNmManagerObj::Launch()
  676. {
  677. if(_Module.InitControlMode())
  678. {
  679. return E_FAIL;
  680. }
  681. else
  682. {
  683. if(!g_pInternalNmManager)
  684. {
  685. if(!CheckRemoteControlService())
  686. {
  687. return E_FAIL;
  688. }
  689. InitConfExe();
  690. }
  691. else
  692. {
  693. ::CreateConfRoomWindow();
  694. }
  695. }
  696. return S_OK;
  697. } // End of CNmManagerObj::Launch.
  698. LPTSTR StripDoubleQuotes(LPTSTR sz)
  699. {
  700. BOOL fSkippedQuote = FALSE;
  701. if (sz)
  702. {
  703. int cchLength;
  704. // Skip past first quote
  705. if (fSkippedQuote = (*sz == '"'))
  706. sz++;
  707. cchLength = lstrlen(sz);
  708. //
  709. // NOTE:
  710. // There may be DBCS implications with this. Hence we check to see
  711. // if we skipped the first quote; we assume that if the file name
  712. // starts with a quote it must end with one also. But we need to check
  713. // it out.
  714. //
  715. // Strip last quote
  716. if (fSkippedQuote && (cchLength > 0) && (sz[cchLength - 1] == '"'))
  717. {
  718. BYTE * pLastQuote = (BYTE *)&sz[cchLength - 1];
  719. *pLastQuote = '\0';
  720. }
  721. }
  722. return sz;
  723. }
  724. STDMETHODIMP CNmManagerObj::LaunchApplet(NM_APPID appid, BSTR strCmdLine)
  725. {
  726. if(!g_pInternalNmManager)
  727. {
  728. if(!CheckRemoteControlService())
  729. {
  730. return E_FAIL;
  731. }
  732. InitConfExe();
  733. }
  734. LPTSTR szName = NULL;
  735. BSTR_to_LPTSTR (&szName, strCmdLine);
  736. switch(appid)
  737. {
  738. case NM_APPID_WHITEBOARD:
  739. CmdShowOldWhiteboard(strCmdLine ? StripDoubleQuotes(szName) : NULL);
  740. break;
  741. case NM_APPID_T126_WHITEBOARD:
  742. ::CmdShowNewWhiteboard(strCmdLine ? StripDoubleQuotes(szName) : NULL);
  743. break;
  744. case NM_APPID_CHAT:
  745. CmdShowChat();
  746. break;
  747. }
  748. if(szName)
  749. {
  750. delete (szName);
  751. }
  752. return S_OK;
  753. }
  754. STDMETHODIMP CNmManagerObj::GetUserData(REFGUID rguid, BYTE **ppb, ULONG *pcb)
  755. {
  756. if(g_pNmSysInfo)
  757. {
  758. return g_pNmSysInfo->GetUserData(rguid, ppb, pcb);
  759. }
  760. return NM_E_NOT_ACTIVE;
  761. }
  762. STDMETHODIMP CNmManagerObj::SetUserData(REFGUID rguid, BYTE *pb, ULONG cb)
  763. {
  764. //
  765. // Special case this guid to allow changing cert via SetUserData
  766. //
  767. if ( g_csguidSecurity == rguid )
  768. {
  769. return SetCertFromCertInfo ( (PCERT_INFO) pb );
  770. }
  771. if(g_pNmSysInfo)
  772. {
  773. return g_pNmSysInfo->SetUserData(rguid, pb, cb);
  774. }
  775. return NM_E_NOT_ACTIVE;
  776. }
  777. STDMETHODIMP CNmManagerObj::DisableH323(BOOL bDisableH323)
  778. {
  779. if(!g_pInternalNmManager)
  780. {
  781. _Module.SetSDKDisableH323(bDisableH323);
  782. return S_OK;
  783. }
  784. return NM_E_ALREADY_RUNNING;
  785. }
  786. STDMETHODIMP CNmManagerObj::SetCallerIsRTC (BOOL bCallerIsRTC)
  787. {
  788. if(!g_pInternalNmManager)
  789. {
  790. _Module.SetSDKCallerIsRTC(bCallerIsRTC);
  791. return S_OK;
  792. }
  793. return NM_E_ALREADY_RUNNING;
  794. }
  795. STDMETHODIMP CNmManagerObj::DisableInitialILSLogon(BOOL bDisable)
  796. {
  797. if(!g_pInternalNmManager)
  798. {
  799. _Module.SetSDKDisableInitialILSLogon(bDisable);
  800. return S_OK;
  801. }
  802. return NM_E_ALREADY_RUNNING;
  803. }
  804. ///////////////////////////////////////////////
  805. // INmManagerNotify methods:
  806. ///////////////////////////////////////////////
  807. STDMETHODIMP CNmManagerObj::NmUI(CONFN uNotify)
  808. {
  809. DBGENTRY(CNmManagerObj::NmUI);
  810. HRESULT hr = S_OK;
  811. // We should not be sending other notifactions
  812. ASSERT(CONFN_NM_STARTED == uNotify);
  813. hr = Fire_NmUI(uNotify);
  814. DBGEXIT_HR(CNmManagerObj::NmUI,hr);
  815. return hr;
  816. }
  817. STDMETHODIMP CNmManagerObj::ConferenceCreated(INmConference *pInternalConference)
  818. {
  819. DBGENTRY(CNmManagerOebj::ConferenceCreated);
  820. HRESULT hr = S_OK;
  821. CComPtr<INmConference> spConf;
  822. hr = CNmConferenceObj::CreateInstance(this, pInternalConference, &spConf);
  823. if(SUCCEEDED(hr))
  824. {
  825. spConf.p->AddRef();
  826. m_SDKConferenceObjs.Add(spConf.p);
  827. Fire_ConferenceCreated(spConf);
  828. if(!CFt::IsFtActive() && FileTransferNotifications())
  829. {
  830. CFt::StartNewConferenceSession();
  831. }
  832. }
  833. DBGEXIT_HR(CNmManagerObj::ConferenceCreated,hr);
  834. return hr;
  835. }
  836. STDMETHODIMP CNmManagerObj::CallCreated(INmCall *pInternalCall)
  837. {
  838. DBGENTRY(CNmManagerObj::CallCreated);
  839. HRESULT hr = S_OK;
  840. if(m_bInitialized)
  841. {
  842. if(NULL == GetSDKCallFromInternalCall(pInternalCall))
  843. {
  844. // First we make sure that we don't have the call object yet
  845. CComPtr<INmCall> spCall;
  846. hr = CNmCallObj::CreateInstance(this, pInternalCall, &spCall);
  847. if(SUCCEEDED(hr))
  848. {
  849. spCall.p->AddRef();
  850. m_SDKCallObjs.Add(spCall.p);
  851. Fire_CallCreated(spCall);
  852. }
  853. }
  854. }
  855. DBGEXIT_HR(CNmManagerObj::CallCreated,hr);
  856. return hr;
  857. }
  858. ///////////////////////////////////////////////
  859. // Notifications
  860. ///////////////////////////////////////////////
  861. HRESULT CNmManagerObj::Fire_ConferenceCreated(INmConference *pConference)
  862. {
  863. DBGENTRY(CNmManagerObj::Fire_ConferenceCreated);
  864. HRESULT hr = S_OK;
  865. // Som SDK clients need this to come in at a specific time....
  866. if(m_bSentConferenceCreated || OfficeMode() && g_bOfficeModeSuspendNotifications)
  867. {
  868. // We don't have to notify anyone at all...
  869. return S_OK;
  870. }
  871. if(!g_bSDKPostNotifications)
  872. {
  873. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  874. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  875. {
  876. m_bSentConferenceCreated = true;
  877. INmManagerNotify* pNotify = reinterpret_cast<INmManagerNotify*>(pCP->m_vec.GetAt(i));
  878. if(pNotify)
  879. {
  880. pNotify->ConferenceCreated(pConference);
  881. // Sinc up the channels, etc.
  882. com_cast<IInternalConferenceObj>(pConference)->FireNotificationsToSyncToInternalObject();
  883. }
  884. }
  885. }
  886. else
  887. {
  888. hr = CSDKWindow::PostConferenceCreated(this, pConference);
  889. }
  890. DBGEXIT_HR(CNmManagerObj::Fire_ConferenceCreated,hr);
  891. return hr;
  892. }
  893. HRESULT CNmManagerObj::Fire_CallCreated(INmCall* pCall)
  894. {
  895. DBGENTRY(CNmManagerObj::Fire_CallCreated);
  896. HRESULT hr = S_OK;
  897. // Always send Outgoing call notifications
  898. // Only send incoming call notifications to INIT CONTROL clients.
  899. if((S_OK != pCall->IsIncoming()) || _Module.InitControlMode())
  900. {
  901. if(!g_bSDKPostNotifications)
  902. {
  903. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  904. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  905. {
  906. INmManagerNotify* pNotify = reinterpret_cast<INmManagerNotify*>(pCP->m_vec.GetAt(i));
  907. if(pNotify)
  908. {
  909. pNotify->CallCreated(pCall);
  910. }
  911. }
  912. }
  913. else
  914. {
  915. hr = CSDKWindow::PostCallCreated(this, pCall);
  916. }
  917. }
  918. DBGEXIT_HR(CNmManagerObj::Fire_CallCreated,hr);
  919. return hr;
  920. }
  921. HRESULT CNmManagerObj::Fire_NmUI(CONFN uNotify)
  922. {
  923. DBGENTRY(CNmManagerObj::Fire_NmUI);
  924. HRESULT hr = S_OK;
  925. // notice the InSendMessage statement.
  926. // The problem is that we can get this notificaiton in
  927. // response to the taskbar icon being clicked. In that case
  928. // an inter-thread SendMessage is occuring. If we try to make
  929. // the NmUi call, we will get RPC_E_CANTCALLOUT_INPUTSYNCCALL
  930. if(!g_bSDKPostNotifications && !InSendMessage())
  931. {
  932. IConnectionPointImpl<CNmManagerObj, &IID_INmManagerNotify, CComDynamicUnkArray>* pCP = this;
  933. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  934. {
  935. INmManagerNotify* pNotify = reinterpret_cast<INmManagerNotify*>(pCP->m_vec.GetAt(i));
  936. if(pNotify)
  937. {
  938. pNotify->NmUI(uNotify);
  939. }
  940. }
  941. }
  942. else
  943. {
  944. hr = CSDKWindow::PostManagerNmUI(this, uNotify);
  945. }
  946. DBGEXIT_HR(CNmManagerObj::Fire_NmUI,hr);
  947. return hr;
  948. }
  949. ///////////////////////////////////////////////
  950. // Helper Fns
  951. ///////////////////////////////////////////////
  952. INmConference* CNmManagerObj::_GetActiveConference()
  953. {
  954. INmConference* pConf = NULL;
  955. if(m_SDKConferenceObjs.GetSize())
  956. {
  957. pConf = m_SDKConferenceObjs[0];
  958. }
  959. return pConf;
  960. }
  961. INmCall* CNmManagerObj::GetSDKCallFromInternalCall(INmCall* pInternalCall)
  962. {
  963. INmCall* pRet = NULL;
  964. for( int i = 0; i < m_SDKCallObjs.GetSize(); ++i)
  965. {
  966. CComQIPtr<IInternalCallObj> spInternal = m_SDKCallObjs[i];
  967. ASSERT(spInternal);
  968. CComPtr<INmCall> spCall;
  969. if(SUCCEEDED(spInternal->GetInternalINmCall(&spCall)))
  970. {
  971. if(spCall.IsEqualObject(pInternalCall))
  972. {
  973. pRet = m_SDKCallObjs[i];
  974. break;
  975. }
  976. }
  977. }
  978. return pRet;
  979. }
  980. INmConference* CNmManagerObj::GetSDKConferenceFromInternalConference(INmConference* pInternalConference)
  981. {
  982. INmConference* pRet = NULL;
  983. for( int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  984. {
  985. CComQIPtr<IInternalConferenceObj> spInternal = m_SDKConferenceObjs[i];
  986. ASSERT(spInternal);
  987. CComPtr<INmConference> spConference;
  988. if(SUCCEEDED(spInternal->GetInternalINmConference(&spConference)))
  989. {
  990. if(spConference.IsEqualObject(pInternalConference))
  991. {
  992. pRet = m_SDKConferenceObjs[i];
  993. break;
  994. }
  995. }
  996. }
  997. return pRet;
  998. }
  999. HRESULT CNmManagerObj::RemoveCall(INmCall* pSDKCallObj)
  1000. {
  1001. HRESULT hr = S_OK;
  1002. for(int i = 0; i < m_SDKCallObjs.GetSize(); ++i)
  1003. {
  1004. CComPtr<INmCall> spSDKCallObj = m_SDKCallObjs[i];
  1005. if(spSDKCallObj.IsEqualObject(pSDKCallObj))
  1006. {
  1007. m_SDKCallObjs.RemoveAt(i);
  1008. spSDKCallObj.p->Release();
  1009. }
  1010. }
  1011. return hr;
  1012. }
  1013. HRESULT CNmManagerObj::RemoveConference(INmConference* pSDKConferenceObj)
  1014. {
  1015. HRESULT hr = S_OK;
  1016. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1017. {
  1018. CComPtr<INmConference> spSDKConferenceObj = m_SDKConferenceObjs[i];
  1019. if(spSDKConferenceObj.IsEqualObject(pSDKConferenceObj))
  1020. {
  1021. m_SDKConferenceObjs.RemoveAt(i);
  1022. spSDKConferenceObj.p->Release();
  1023. }
  1024. }
  1025. return hr;
  1026. }
  1027. bool CNmManagerObj::AudioNotifications()
  1028. {
  1029. return m_bInitialized && (m_chCaps & NMCH_AUDIO);
  1030. }
  1031. bool CNmManagerObj::VideoNotifications()
  1032. {
  1033. return m_bInitialized && (m_chCaps & NMCH_VIDEO);
  1034. }
  1035. bool CNmManagerObj::DataNotifications()
  1036. {
  1037. return m_bInitialized && (m_chCaps & NMCH_DATA);
  1038. }
  1039. bool CNmManagerObj::FileTransferNotifications()
  1040. {
  1041. return m_bInitialized && (m_chCaps & NMCH_FT);
  1042. }
  1043. bool CNmManagerObj::AppSharingNotifications()
  1044. {
  1045. return m_bInitialized && (m_chCaps & NMCH_SHARE);
  1046. }
  1047. //static
  1048. void CNmManagerObj::NetMeetingLaunched()
  1049. {
  1050. ASSERT(ms_pManagerObjList);
  1051. if(ms_pManagerObjList)
  1052. {
  1053. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1054. {
  1055. (*ms_pManagerObjList)[i]->Fire_NmUI(CONFN_NM_STARTED);
  1056. }
  1057. }
  1058. }
  1059. //static
  1060. void CNmManagerObj::SharableAppStateChanged(HWND hWnd, NM_SHAPP_STATE state)
  1061. {
  1062. if(ms_pManagerObjList)
  1063. {
  1064. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1065. {
  1066. (*ms_pManagerObjList)[i]->_SharableAppStateChanged(hWnd, state);
  1067. }
  1068. }
  1069. }
  1070. void CNmManagerObj::_SharableAppStateChanged(HWND hWnd, NM_SHAPP_STATE state)
  1071. {
  1072. // Free our conferencing objects
  1073. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1074. {
  1075. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->SharableAppStateChanged(hWnd, state);
  1076. }
  1077. }
  1078. //static
  1079. void CNmManagerObj::AppSharingChannelChanged()
  1080. {
  1081. if(ms_pManagerObjList)
  1082. {
  1083. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1084. {
  1085. (*ms_pManagerObjList)[i]->_AppSharingChannelChanged();
  1086. }
  1087. }
  1088. }
  1089. void CNmManagerObj::_AppSharingChannelChanged()
  1090. {
  1091. // Free our conferencing objects
  1092. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1093. {
  1094. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->AppSharingChannelChanged();
  1095. }
  1096. }
  1097. //static
  1098. void CNmManagerObj::AppSharingChannelActiveStateChanged(bool bActive)
  1099. {
  1100. if(ms_pManagerObjList)
  1101. {
  1102. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1103. {
  1104. (*ms_pManagerObjList)[i]->_AppSharingChannelActiveStateChanged(bActive);
  1105. }
  1106. }
  1107. }
  1108. void CNmManagerObj::_AppSharingChannelActiveStateChanged(bool bActive)
  1109. {
  1110. // Free our conferencing objects
  1111. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1112. {
  1113. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->AppSharingStateChanged(bActive);
  1114. }
  1115. }
  1116. //static
  1117. void CNmManagerObj::ASLocalMemberChanged()
  1118. {
  1119. if(ms_pManagerObjList)
  1120. {
  1121. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1122. {
  1123. (*ms_pManagerObjList)[i]->_ASLocalMemberChanged();
  1124. }
  1125. }
  1126. }
  1127. void CNmManagerObj::_ASLocalMemberChanged()
  1128. {
  1129. // notify our conferencing objects
  1130. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1131. {
  1132. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->ASLocalMemberChanged();
  1133. }
  1134. }
  1135. //static
  1136. void CNmManagerObj::ASMemberChanged(UINT gccID)
  1137. {
  1138. if(ms_pManagerObjList)
  1139. {
  1140. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1141. {
  1142. (*ms_pManagerObjList)[i]->_ASMemberChanged(gccID);
  1143. }
  1144. }
  1145. }
  1146. void CNmManagerObj::_ASMemberChanged(UINT gccID)
  1147. {
  1148. // notify our conferencing objects
  1149. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1150. {
  1151. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->ASMemberChanged(gccID);
  1152. }
  1153. }
  1154. // static
  1155. void CNmManagerObj::AudioChannelActiveState(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]->_AudioChannelActiveState(bActive, bIsIncoming);
  1162. }
  1163. }
  1164. }
  1165. void CNmManagerObj::_AudioChannelActiveState(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])->AudioChannelActiveState(bActive ? TRUE : FALSE, bIsIncoming);
  1171. }
  1172. }
  1173. // static
  1174. void CNmManagerObj::VideoChannelActiveState(BOOL bActive, BOOL bIsIncoming)
  1175. {
  1176. if(ms_pManagerObjList)
  1177. {
  1178. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1179. {
  1180. (*ms_pManagerObjList)[i]->_VideoChannelActiveState(bActive, bIsIncoming);
  1181. }
  1182. }
  1183. }
  1184. void CNmManagerObj::_VideoChannelActiveState(BOOL bActive, 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])->VideoChannelActiveState(bActive ? TRUE : FALSE, bIsIncoming);
  1190. }
  1191. }
  1192. // static
  1193. void CNmManagerObj::VideoPropChanged(DWORD dwProp, BOOL bIsIncoming)
  1194. {
  1195. if(ms_pManagerObjList)
  1196. {
  1197. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1198. {
  1199. (*ms_pManagerObjList)[i]->_VideoPropChanged(dwProp, bIsIncoming);
  1200. }
  1201. }
  1202. }
  1203. void CNmManagerObj::_VideoPropChanged(DWORD dwProp, 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])->VideoChannelPropChanged(dwProp, bIsIncoming);
  1209. }
  1210. }
  1211. // static
  1212. void CNmManagerObj::VideoChannelStateChanged(NM_VIDEO_STATE uState, BOOL bIsIncoming)
  1213. {
  1214. if(ms_pManagerObjList)
  1215. {
  1216. for( int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1217. {
  1218. (*ms_pManagerObjList)[i]->_VideoChannelStateChanged(uState, bIsIncoming);
  1219. }
  1220. }
  1221. }
  1222. void CNmManagerObj::_VideoChannelStateChanged(NM_VIDEO_STATE uState, BOOL bIsIncoming)
  1223. {
  1224. // notify our conferencing objects
  1225. for(int i = 0; i < m_SDKConferenceObjs.GetSize(); ++i)
  1226. {
  1227. com_cast<IInternalConferenceObj>(m_SDKConferenceObjs[i])->VideoChannelStateChanged(uState, bIsIncoming);
  1228. }
  1229. }
  1230. UINT CNmManagerObj::GetManagerCount(ULONG uOption)
  1231. {
  1232. UINT nMgrs = 0;
  1233. for(int i = 0; i < ms_pManagerObjList->GetSize(); ++i)
  1234. {
  1235. if(uOption == (*ms_pManagerObjList)[i]->m_uOptions)
  1236. {
  1237. nMgrs++;
  1238. }
  1239. }
  1240. return nMgrs;
  1241. }
  1242. void CNmManagerObj::OnShowUI(BOOL fShow)
  1243. {
  1244. _Module.SetUIVisible(fShow);
  1245. if (fShow)
  1246. {
  1247. CConfMan::AllowAV(TRUE);
  1248. }
  1249. else
  1250. {
  1251. if(0 != GetManagerCount(NM_INIT_OBJECT))
  1252. {
  1253. CConfMan::AllowAV(FALSE);
  1254. }
  1255. }
  1256. }
  1257. HRESULT CNmManagerObj::SdkPlaceCall(NM_CALL_TYPE callType,
  1258. NM_ADDR_TYPE addrType,
  1259. BSTR bstrAddr,
  1260. BSTR bstrConf,
  1261. BSTR bstrPw,
  1262. INmCall **ppInternalCall)
  1263. {
  1264. HRESULT hr;
  1265. LPTSTR szAddr = NULL;
  1266. LPTSTR szConf = NULL;
  1267. LPTSTR szPw = NULL;
  1268. DWORD dwFlags = MapNmCallTypeToCallFlags(callType, addrType, g_uMediaCaps);
  1269. if (0 == dwFlags)
  1270. {
  1271. hr = NM_CALLERR_MEDIA;
  1272. goto end;
  1273. }
  1274. {
  1275. BSTR_to_LPTSTR (&szAddr, bstrAddr);
  1276. if(NM_ADDR_T120_TRANSPORT == addrType)
  1277. {
  1278. //
  1279. // Check if "+secure=true" parameter was passed
  1280. //
  1281. CCalltoParams params;
  1282. bool bSecure = FALSE;
  1283. params.SetParams(szAddr);
  1284. bSecure = params.GetBooleanParam("secure",bSecure);
  1285. //
  1286. // Yes it was in the parameters.
  1287. // Now make sure to remove it
  1288. // The addre now is like "111.222.333.444+secure=true"
  1289. // The call will only work if we pass the ip address only
  1290. //
  1291. if(bSecure)
  1292. {
  1293. // Get the syze of the bstr
  1294. int cch = lstrlen(szAddr);
  1295. BYTE *pByte = (BYTE *) szAddr;
  1296. for(int i = 0; i < cch;i++)
  1297. {
  1298. // Null terminate the string
  1299. if(*pByte == '+')
  1300. {
  1301. *pByte = '\0';
  1302. break;
  1303. }
  1304. pByte++;
  1305. }
  1306. dwFlags |= CRPCF_SECURE;
  1307. }
  1308. }
  1309. CCallResolver CallResolver(szAddr, addrType);
  1310. hr = CallResolver.Resolve();
  1311. if (FAILED(hr))
  1312. {
  1313. goto end;
  1314. }
  1315. CCall* pCall = new CCall(CallResolver.GetPszAddr(), szAddr, NM_ADDR_CALLTO, FALSE, FALSE);
  1316. if(NULL == pCall)
  1317. {
  1318. goto end;
  1319. }
  1320. pCall->AddRef();
  1321. switch(CallResolver.GetAddrType())
  1322. {
  1323. case NM_ADDR_ULS:
  1324. case NM_ADDR_IP:
  1325. case NM_ADDR_MACHINENAME:
  1326. case NM_ADDR_H323_GATEWAY:
  1327. ASSERT(FIpAddress(CallResolver.GetPszAddrIP()));
  1328. /////////////////////////////////////////////
  1329. // !!!!! HEY RYAN, WERE FALLING THROUGH !!!!!
  1330. /////////////////////////////////////////////
  1331. case NM_ADDR_T120_TRANSPORT:
  1332. BSTR_to_LPTSTR (&szConf, bstrConf);
  1333. BSTR_to_LPTSTR (&szPw, bstrPw);
  1334. hr = pCall->PlaceCall(
  1335. dwFlags, // dwFlags
  1336. CallResolver.GetAddrType(), // addrType
  1337. NULL, // szSetup
  1338. (NM_ADDR_T120_TRANSPORT == CallResolver.GetAddrType()) ?
  1339. CallResolver.GetPszAddr() :
  1340. CallResolver.GetPszAddrIP(), // szDestination
  1341. CallResolver.GetPszAddr(),// szAlias
  1342. NULL, // szURL
  1343. (szConf), // szConference
  1344. (szPw), // szPassword
  1345. NULL); // szUserData
  1346. break;
  1347. default:
  1348. ERROR_OUT(("Don't know this call type"));
  1349. ASSERT(0);
  1350. break;
  1351. }
  1352. if( FAILED(hr) && (pCall->GetState() == NM_CALL_INVALID ) )
  1353. {
  1354. // just release the call to free the data
  1355. // otherwise wait for the call state to be changed
  1356. pCall->Release();
  1357. }
  1358. if(ppInternalCall && SUCCEEDED(hr))
  1359. {
  1360. *ppInternalCall = pCall->GetINmCall();
  1361. (*ppInternalCall)->AddRef();
  1362. }
  1363. pCall->Release();
  1364. }
  1365. end:
  1366. if( FAILED( hr ) && _Module.IsUIActive() )
  1367. {
  1368. DisplayCallError( hr, szAddr );
  1369. }
  1370. delete szAddr;
  1371. delete szConf;
  1372. delete szPw;
  1373. return hr;
  1374. }
  1375. DWORD CNmManagerObj::MapNmCallTypeToCallFlags(NM_CALL_TYPE callType, NM_ADDR_TYPE addrType, UINT uCaps)
  1376. {
  1377. DWORD dwFlags = 0;
  1378. BOOL fForceSecure = FALSE;
  1379. // Check global conference status
  1380. if (INmConference *pConf = ::GetActiveConference())
  1381. {
  1382. // We are in a conference. Use the conference security setting.
  1383. DWORD dwCaps;
  1384. if ((S_OK == pConf->GetNmchCaps(&dwCaps)) &&
  1385. (NMCH_SECURE & dwCaps))
  1386. {
  1387. fForceSecure = TRUE;
  1388. }
  1389. }
  1390. else
  1391. {
  1392. fForceSecure = (REQUIRED_POL_SECURITY == ConfPolicies::GetSecurityLevel());
  1393. }
  1394. switch(addrType)
  1395. {
  1396. case NM_ADDR_T120_TRANSPORT:
  1397. dwFlags = CRPCF_T120 | CRPCF_DATA;
  1398. if(ConfPolicies::OutgoingSecurityPreferred() || fForceSecure)
  1399. {
  1400. dwFlags |= CRPCF_SECURE;
  1401. }
  1402. break;
  1403. default:
  1404. switch (callType)
  1405. {
  1406. case NM_CALL_T120:
  1407. if (fForceSecure)
  1408. {
  1409. dwFlags = CRPCF_T120 | CRPCF_DATA | CRPCF_SECURE;
  1410. }
  1411. else
  1412. {
  1413. dwFlags = CRPCF_T120 | CRPCF_DATA;
  1414. }
  1415. break;
  1416. case NM_CALL_H323:
  1417. if (!fForceSecure)
  1418. {
  1419. dwFlags = CRPCF_H323CC;
  1420. if (uCaps & (CAPFLAG_RECV_AUDIO | CAPFLAG_SEND_AUDIO))
  1421. dwFlags |= CRPCF_AUDIO;
  1422. if (uCaps & (CAPFLAG_RECV_VIDEO | CAPFLAG_SEND_VIDEO))
  1423. dwFlags |= CRPCF_VIDEO;
  1424. }
  1425. break;
  1426. case NM_CALL_DEFAULT:
  1427. if (fForceSecure)
  1428. {
  1429. dwFlags = CRPCF_T120 | CRPCF_DATA | CRPCF_SECURE;
  1430. }
  1431. else
  1432. {
  1433. dwFlags = CRPCF_DEFAULT;
  1434. // strip AV if policies prohibit
  1435. if((uCaps & (CAPFLAG_RECV_AUDIO |CAPFLAG_SEND_AUDIO)) == 0)
  1436. {
  1437. dwFlags &= ~CRPCF_AUDIO;
  1438. }
  1439. if((uCaps & (CAPFLAG_RECV_VIDEO |CAPFLAG_SEND_VIDEO)) == 0)
  1440. {
  1441. dwFlags &= ~CRPCF_VIDEO;
  1442. }
  1443. }
  1444. break;
  1445. default:
  1446. dwFlags = 0;
  1447. break;
  1448. }
  1449. }
  1450. return dwFlags;
  1451. }