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.

656 lines
12 KiB

  1. #include "precomp.h"
  2. // NetMeeting SDK includes
  3. #include "NmEnum.h"
  4. #include "NmCall.h"
  5. #include "NmApp.h"
  6. #include "NmManager.h"
  7. #include "NmConference.h"
  8. #include "SDKWindow.h"
  9. //////////////////////////////////////////
  10. // Static Data
  11. //////////////////////////////////////////
  12. /*static*/ CSimpleArray<CNmCallObj*>* CNmCallObj::ms_pCallObjList = NULL;
  13. //////////////////////////////////////////
  14. // Construction and destruction
  15. //////////////////////////////////////////
  16. CNmCallObj::CNmCallObj()
  17. : m_pNmManagerObj(NULL),
  18. m_State(NM_CALL_INIT)
  19. {
  20. DBGENTRY(CNmCallObj::CNmCallObj);
  21. if(ms_pCallObjList)
  22. {
  23. CNmCallObj* p = const_cast<CNmCallObj*>(this);
  24. ms_pCallObjList->Add(p);
  25. }
  26. else
  27. {
  28. ERROR_OUT(("ms_pCallObjList is NULL"));
  29. }
  30. DBGEXIT(CNmCallObj::CNmCallObj);
  31. }
  32. HRESULT CNmCallObj::FinalConstruct()
  33. {
  34. DBGENTRY(CNmCallObj::FinalConstruct);
  35. HRESULT hr = S_OK;
  36. RECT rc;
  37. m_dwInteralINmCallAdvise = 0;
  38. DBGEXIT_HR(CNmCallObj::FinalConstruct,hr);
  39. return hr;
  40. }
  41. CNmCallObj::~CNmCallObj()
  42. {
  43. DBGENTRY(CNmCallObj::~CNmCallObj);
  44. if(ms_pCallObjList)
  45. {
  46. CNmCallObj* p = const_cast<CNmCallObj*>(this);
  47. ms_pCallObjList->Remove(p);
  48. }
  49. else
  50. {
  51. ERROR_OUT(("ms_pCallObjList is NULL"));
  52. }
  53. DBGEXIT(CNmCallObj::~CNmCallObj);
  54. }
  55. ULONG CNmCallObj::InternalRelease()
  56. {
  57. ATLASSERT(m_dwRef > 0);
  58. --m_dwRef;
  59. if((1 == m_dwRef) && m_dwInteralINmCallAdvise)
  60. {
  61. CComQIPtr<INmCall> spCall = GetUnknown();
  62. DWORD dwAdvise = m_dwInteralINmCallAdvise;
  63. m_dwInteralINmCallAdvise = 0;
  64. CComPtr<INmCall> spInternalCall = m_spInternalINmCall;
  65. m_spInternalINmCall = NULL;
  66. AtlUnadvise(spInternalCall, IID_INmCallNotify2,dwAdvise);
  67. }
  68. return m_dwRef;
  69. }
  70. //static
  71. HRESULT CNmCallObj::CreateInstance(CNmManagerObj* pNmManagerObj, INmCall* pInternalINmCall, INmCall** ppCall)
  72. {
  73. DBGENTRY(CNmCallObj::CreateInstance);
  74. HRESULT hr = S_OK;
  75. CComObject<CNmCallObj>* p = NULL;
  76. p = new CComObject<CNmCallObj>(NULL);
  77. if(p)
  78. {
  79. p->m_spInternalINmCall = pInternalINmCall;
  80. // We don't have to addref because our lifetime is enclosed within the CNmManagerObj
  81. p->m_pNmManagerObj = pNmManagerObj;
  82. hr = _CreateInstanceGuts(p, ppCall);
  83. if(SUCCEEDED(hr))
  84. {
  85. hr = AtlAdvise(pInternalINmCall, *ppCall, IID_INmCallNotify2, &p->m_dwInteralINmCallAdvise);
  86. if(FAILED(hr))
  87. {
  88. delete p;
  89. }
  90. }
  91. }
  92. else
  93. {
  94. hr = E_OUTOFMEMORY;
  95. }
  96. DBGEXIT_HR(CNmCallObj::CreateInstance,hr);
  97. return hr;
  98. }
  99. /*static*/
  100. HRESULT CNmCallObj::_CreateInstanceGuts(CComObject<CNmCallObj> *p, INmCall** ppCall)
  101. {
  102. DBGENTRY(CNmCallObj::_CreateInstanceGuts);
  103. HRESULT hr = S_OK;
  104. if(ppCall)
  105. {
  106. if(ms_pCallObjList)
  107. {
  108. if(p != NULL)
  109. {
  110. p->SetVoid(NULL);
  111. p->InternalFinalConstructAddRef();
  112. hr = p->FinalConstruct();
  113. p->InternalFinalConstructRelease();
  114. if(hr == S_OK)
  115. hr = p->QueryInterface(IID_INmCall, reinterpret_cast<void**>(ppCall));
  116. if(FAILED(hr))
  117. {
  118. *ppCall = NULL;
  119. delete p;
  120. }
  121. }
  122. else
  123. {
  124. hr = E_UNEXPECTED;
  125. }
  126. }
  127. else
  128. {
  129. ERROR_OUT(("You must first call InitSDK!"));
  130. hr = E_UNEXPECTED;
  131. }
  132. }
  133. else
  134. {
  135. hr = E_POINTER;
  136. }
  137. DBGEXIT_HR(CNmCallObj::_CreateInstanceGuts,hr);
  138. return hr;
  139. }
  140. /*static*/ HRESULT CNmCallObj::InitSDK()
  141. {
  142. DBGENTRY(CNmCallObj::InitSDK);
  143. HRESULT hr = S_OK;
  144. if(!ms_pCallObjList)
  145. {
  146. ms_pCallObjList = new CSimpleArray<CNmCallObj*>;
  147. if(!ms_pCallObjList)
  148. {
  149. hr = E_OUTOFMEMORY;
  150. }
  151. }
  152. else
  153. {
  154. hr = E_UNEXPECTED;
  155. }
  156. DBGEXIT_HR(CNmCallObj::InitSDK,hr);
  157. return hr;
  158. }
  159. /*static*/void CNmCallObj::CleanupSDK()
  160. {
  161. DBGENTRY(CNmCallObj::CleanupSDK);
  162. delete ms_pCallObjList;
  163. ms_pCallObjList = NULL;
  164. DBGEXIT(CNmCallObj::CleanupSDK);
  165. }
  166. //////////////////////////////////////////
  167. // INmCall
  168. //////////////////////////////////////////
  169. STDMETHODIMP CNmCallObj::IsIncoming(void)
  170. {
  171. DBGENTRY(CNmCallObj::IsIncoming);
  172. HRESULT hr = S_OK;
  173. if(m_spInternalINmCall)
  174. {
  175. hr = m_spInternalINmCall->IsIncoming();
  176. }
  177. else
  178. {
  179. hr = E_UNEXPECTED;
  180. ERROR_OUT(("Why don't I have an internal INmCall??"));
  181. }
  182. DBGEXIT_HR(CNmCallObj::IsIncoming,hr);
  183. return hr;
  184. }
  185. STDMETHODIMP CNmCallObj::GetState(NM_CALL_STATE *pState)
  186. {
  187. DBGENTRY(CNmCallObj::GetState);
  188. HRESULT hr = S_OK;
  189. if(pState)
  190. {
  191. *pState = m_State;
  192. }
  193. else
  194. {
  195. hr = E_POINTER;
  196. }
  197. DBGEXIT_HR(CNmCallObj::GetState,hr);
  198. return hr;
  199. }
  200. STDMETHODIMP CNmCallObj::GetName(BSTR *pbstrName)
  201. {
  202. DBGENTRY(CNmCallObj::GetName);
  203. HRESULT hr = E_FAIL;
  204. if(m_spInternalINmCall)
  205. {
  206. hr = m_spInternalINmCall->GetName(pbstrName);
  207. }
  208. DBGEXIT_HR(CNmCallObj::GetName,hr);
  209. return hr;
  210. }
  211. STDMETHODIMP CNmCallObj::GetAddr(BSTR *pbstrAddr, NM_ADDR_TYPE * puType)
  212. {
  213. DBGENTRY(CNmCallObj::GetAddr);
  214. HRESULT hr = E_FAIL;
  215. if(m_spInternalINmCall)
  216. {
  217. hr = m_spInternalINmCall->GetAddr(pbstrAddr, puType);
  218. }
  219. DBGEXIT_HR(CNmCallObj::GetAddr,hr);
  220. return hr;
  221. }
  222. STDMETHODIMP CNmCallObj::GetUserData(REFGUID rguid, BYTE **ppb, ULONG *pcb)
  223. {
  224. DBGENTRY(CNmCallObj::GetUserData);
  225. HRESULT hr = S_OK;
  226. if(m_spInternalINmCall)
  227. {
  228. hr = m_spInternalINmCall->GetUserData(rguid, ppb, pcb);
  229. }
  230. else
  231. {
  232. hr = E_UNEXPECTED;
  233. ERROR_OUT(("Why don't I have an internal INmCall??"));
  234. }
  235. DBGEXIT_HR(CNmCallObj::GetUserData,hr);
  236. return hr;
  237. }
  238. STDMETHODIMP CNmCallObj::GetConference(INmConference **ppConference)
  239. {
  240. DBGENTRY(CNmCallObj::GetConference);
  241. HRESULT hr = S_OK;
  242. if(ppConference)
  243. {
  244. *ppConference = m_spConference;
  245. if(*ppConference)
  246. {
  247. (*ppConference)->AddRef();
  248. }
  249. else
  250. {
  251. hr = S_FALSE;
  252. }
  253. }
  254. else
  255. {
  256. hr = E_POINTER;
  257. }
  258. DBGEXIT_HR(CNmCallObj::GetConference,hr);
  259. return hr;
  260. }
  261. STDMETHODIMP CNmCallObj::Accept(void)
  262. {
  263. DBGENTRY(CNmCallObj::Accept);
  264. HRESULT hr = S_OK;
  265. g_bSDKPostNotifications = true;
  266. if(m_spInternalINmCall)
  267. {
  268. m_spInternalINmCall->Accept();
  269. }
  270. else
  271. {
  272. hr = E_UNEXPECTED;
  273. }
  274. g_bSDKPostNotifications = false;
  275. DBGEXIT_HR(CNmCallObj::Accept,hr);
  276. return hr;
  277. }
  278. STDMETHODIMP CNmCallObj::Reject(void)
  279. {
  280. DBGENTRY(CNmCallObj::Reject);
  281. HRESULT hr = S_OK;
  282. g_bSDKPostNotifications = true;
  283. if(m_spInternalINmCall)
  284. {
  285. m_spInternalINmCall->Reject();
  286. }
  287. else
  288. {
  289. hr = E_UNEXPECTED;
  290. }
  291. g_bSDKPostNotifications = false;
  292. DBGEXIT_HR(CNmCallObj::Reject,hr);
  293. return hr;
  294. }
  295. STDMETHODIMP CNmCallObj::Cancel(void)
  296. {
  297. DBGENTRY(CNmCallObj::Cancel);
  298. HRESULT hr = S_OK;
  299. g_bSDKPostNotifications = true;
  300. if(m_spInternalINmCall)
  301. {
  302. m_spInternalINmCall->Cancel();
  303. }
  304. else
  305. {
  306. hr = E_UNEXPECTED;
  307. }
  308. g_bSDKPostNotifications = false;
  309. DBGEXIT_HR(CNmCallObj::Cancel,hr);
  310. return hr;
  311. }
  312. ////////////////////////////////////////////////
  313. // INmCallNotify methods
  314. ////////////////////////////////////////////////
  315. STDMETHODIMP CNmCallObj::NmUI(CONFN uNotify)
  316. {
  317. DBGENTRY(CNmCallObj::NmUI);
  318. HRESULT hr = S_OK;
  319. hr = Fire_NmUI(uNotify);
  320. DBGEXIT_HR(CNmCallObj::NmUI,hr);
  321. return hr;
  322. }
  323. STDMETHODIMP CNmCallObj::StateChanged(NM_CALL_STATE uState)
  324. {
  325. DBGENTRY(CNmCallObj::StateChanged);
  326. HRESULT hr = S_OK;
  327. if(m_State != uState)
  328. {
  329. m_State = uState;
  330. Fire_StateChanged(uState);
  331. }
  332. DBGEXIT_HR(CNmCallObj::StateChanged,hr);
  333. return hr;
  334. }
  335. STDMETHODIMP CNmCallObj::Failed(ULONG uError)
  336. {
  337. DBGENTRY(CNmCallObj::Failed);
  338. HRESULT hr = S_OK;
  339. hr = Fire_Failed(uError);
  340. DBGEXIT_HR(CNmCallObj::Failed,hr);
  341. return hr;
  342. }
  343. STDMETHODIMP CNmCallObj::Accepted(INmConference *pInternalConference)
  344. {
  345. DBGENTRY(CNmCallObj::Accepted);
  346. HRESULT hr = E_NOTIMPL;
  347. if(m_pNmManagerObj)
  348. {
  349. INmConference* pSDKConference = m_pNmManagerObj->GetSDKConferenceFromInternalConference(pInternalConference);
  350. if(pSDKConference)
  351. {
  352. pSDKConference->AddRef();
  353. Fire_Accepted(pSDKConference);
  354. pSDKConference->Release();
  355. }
  356. }
  357. DBGEXIT_HR(CNmCallObj::Accepted,hr);
  358. return hr;
  359. }
  360. ///////////////////////////////////////////////////////////////////////
  361. // IInternalCallObj methods
  362. ///////////////////////////////////////////////////////////////////////
  363. STDMETHODIMP CNmCallObj::GetInternalINmCall(INmCall** ppCall)
  364. {
  365. DBGENTRY(CNmCallObj::GetInternalINmCall);
  366. HRESULT hr = S_OK;
  367. ASSERT(ppCall);
  368. *ppCall = m_spInternalINmCall;
  369. (*ppCall)->AddRef();
  370. DBGEXIT_HR(CNmCallObj::GetInternalINmCall,hr);
  371. return hr;
  372. }
  373. ////////////////////////////////////////////////
  374. // Helper fns
  375. ////////////////////////////////////////////////
  376. HRESULT CNmCallObj::_ReleaseResources()
  377. {
  378. HRESULT hr = S_OK;
  379. return hr;
  380. }
  381. //////////////////////////////////////////////////////////////////////
  382. // Notification Firing Fns
  383. /////////////////////////////////////////////////////////////////////
  384. // static
  385. HRESULT CNmCallObj::StateChanged(INmCall* pInternalNmCall, NM_CALL_STATE uState)
  386. {
  387. DBGENTRY(CNmCallObj::StateChanged);
  388. HRESULT hr = S_OK;
  389. if(ms_pCallObjList)
  390. {
  391. hr = E_FAIL;
  392. for(int i = 0; i < ms_pCallObjList->GetSize(); ++i)
  393. {
  394. if(pInternalNmCall == (*ms_pCallObjList)[i]->m_spInternalINmCall)
  395. {
  396. (*ms_pCallObjList)[i]->StateChanged(uState);
  397. break;
  398. }
  399. }
  400. }
  401. else
  402. {
  403. ERROR_OUT(("ms_pCallObjList is null!"));
  404. }
  405. DBGEXIT_HR(CNmCallObj::StateChanged,hr);
  406. return hr;
  407. }
  408. HRESULT CNmCallObj::Fire_NmUI(CONFN uNotify)
  409. {
  410. DBGENTRY(CNmCallObj::Fire_NmUI);
  411. HRESULT hr = S_OK;
  412. if(!g_bSDKPostNotifications)
  413. {
  414. /////////////////////////////////////////////////////
  415. // INmCallNotify
  416. /////////////////////////////////////////////////////
  417. IConnectionPointImpl<CNmCallObj, &IID_INmCallNotify, CComDynamicUnkArray>* pCP = this;
  418. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  419. {
  420. INmCallNotify* pNotify = reinterpret_cast<INmCallNotify*>(pCP->m_vec.GetAt(i));
  421. if(pNotify)
  422. {
  423. pNotify->NmUI(uNotify);
  424. }
  425. }
  426. }
  427. else
  428. {
  429. CSDKWindow::PostCallNmUi(this, uNotify);
  430. }
  431. DBGEXIT_HR(CNmCallObj::Fire_NmUI,hr);
  432. return hr;
  433. }
  434. HRESULT CNmCallObj::Fire_StateChanged(NM_CALL_STATE uState)
  435. {
  436. DBGENTRY(CNmCallObj::Fire_StateChanged);
  437. HRESULT hr = S_OK;
  438. if(!g_bSDKPostNotifications)
  439. {
  440. /////////////////////////////////////////////////////
  441. // INmCallNotify
  442. /////////////////////////////////////////////////////
  443. IConnectionPointImpl<CNmCallObj, &IID_INmCallNotify, CComDynamicUnkArray>* pCP = this;
  444. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  445. {
  446. INmCallNotify* pNotify = reinterpret_cast<INmCallNotify*>(pCP->m_vec.GetAt(i));
  447. if(pNotify)
  448. {
  449. pNotify->StateChanged(uState);
  450. }
  451. }
  452. }
  453. else
  454. {
  455. CSDKWindow::PostCallStateChanged(this, uState);
  456. }
  457. DBGEXIT_HR(CNmCallObj::Fire_StateChanged,hr);
  458. return hr;
  459. }
  460. HRESULT CNmCallObj::Fire_Failed(ULONG uError)
  461. {
  462. DBGENTRY(CNmCallObj::Fire_Failed);
  463. HRESULT hr = S_OK;
  464. if(!g_bSDKPostNotifications)
  465. {
  466. /////////////////////////////////////////////////////
  467. // INmCallNotify
  468. /////////////////////////////////////////////////////
  469. IConnectionPointImpl<CNmCallObj, &IID_INmCallNotify, CComDynamicUnkArray>* pCP = this;
  470. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  471. {
  472. INmCallNotify* pNotify = reinterpret_cast<INmCallNotify*>(pCP->m_vec.GetAt(i));
  473. if(pNotify)
  474. {
  475. pNotify->Failed(uError);
  476. }
  477. }
  478. }
  479. else
  480. {
  481. CSDKWindow::PostFailed(this, uError);
  482. }
  483. DBGEXIT_HR(CNmCallObj::Fire_Failed,hr);
  484. return hr;
  485. }
  486. HRESULT CNmCallObj::Fire_Accepted(INmConference* pConference)
  487. {
  488. DBGENTRY(CNmCallObj::Fire_Accepted);
  489. HRESULT hr = S_OK;
  490. if(!g_bSDKPostNotifications)
  491. {
  492. /////////////////////////////////////////////////////
  493. // INmCallNotify
  494. /////////////////////////////////////////////////////
  495. IConnectionPointImpl<CNmCallObj, &IID_INmCallNotify, CComDynamicUnkArray>* pCP = this;
  496. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  497. {
  498. INmCallNotify* pNotify = reinterpret_cast<INmCallNotify*>(pCP->m_vec.GetAt(i));
  499. if(pNotify)
  500. {
  501. pNotify->Accepted(pConference);
  502. }
  503. }
  504. }
  505. else
  506. {
  507. CSDKWindow::PostAccepted(this, pConference);
  508. }
  509. DBGEXIT_HR(CNmCallObj::Fire_Accepted,hr);
  510. return hr;
  511. }
  512. //////////////////////////////////////////////////////////////////////
  513. // Helper Fns
  514. //////////////////////////////////////////////////////////////////////