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.

461 lines
9.3 KiB

  1. #ifndef __NmChannel_h__
  2. #define __NmChannel_h__
  3. #include "imsconf3.h"
  4. class CNmConferenceObj;
  5. template<class T, const IID* piid, DWORD dwCh>
  6. class ATL_NO_VTABLE CNmChannel : public T
  7. {
  8. friend class CNmChannelDataObj;
  9. friend class CNmChannelAudioObj;
  10. friend class CNmChannelVideoObj;
  11. friend class CNmChannelFtObj;
  12. friend class CNmChannelAppShareObj;
  13. public:
  14. CNmChannel() : m_bActive(false), m_pConfObj(NULL) { ; }
  15. ~CNmChannel()
  16. {
  17. DBGENTRY(CNmChannel::~CNmChannel);
  18. RemoveMembers();
  19. DBGEXIT(CNmChannel::~CNmChannel);
  20. }
  21. // INmChannel methods
  22. STDMETHOD(IsSameAs)(INmChannel *pChannel);
  23. STDMETHOD(IsActive)(void);
  24. STDMETHOD(SetActive)(BOOL fActive);
  25. STDMETHOD(GetConference)(INmConference **ppConference);
  26. STDMETHOD(GetInterface)(IID *_piid);
  27. STDMETHOD(GetNmch)(ULONG *puCh);
  28. STDMETHOD(EnumMember)(IEnumNmMember **ppEnum);
  29. STDMETHOD(GetMemberCount)(ULONG * puCount);
  30. // INmChannelNotify
  31. STDMETHOD(NmUI)(CONFN uNotify);
  32. STDMETHOD(MemberChanged)(NM_MEMBER_NOTIFY uNotify, INmMember *pInternalMember);
  33. STDMETHOD(NotifySinksOfAllMembers)()
  34. {
  35. for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  36. {
  37. Fire_MemberChanged(NM_MEMBER_ADDED, m_SDKMemberObjs[i]);
  38. }
  39. return S_OK;
  40. }
  41. STDMETHOD(NotifySinksOfLocalMember)()
  42. {
  43. Fire_MemberChanged(NM_MEMBER_ADDED, GetConfObj()->GetLocalSDKMember());
  44. return S_OK;
  45. }
  46. virtual bool IsChannelValid()
  47. {
  48. if(m_pConfObj)
  49. {
  50. NM_CONFERENCE_STATE state;
  51. if(SUCCEEDED(m_pConfObj->GetState(&state)) && (NM_CONFERENCE_IDLE != state))
  52. {
  53. return true;
  54. }
  55. }
  56. return false;
  57. }
  58. virtual CNmConferenceObj* GetConfObj() { return m_pConfObj; }
  59. virtual BOOL GetbActive() { return m_bActive; }
  60. virtual void RemoveMembers()
  61. {
  62. // Free our conferencing objects
  63. while(m_SDKMemberObjs.GetSize())
  64. {
  65. Fire_MemberChanged(NM_MEMBER_REMOVED, m_SDKMemberObjs[0]);
  66. CComPtr<INmMember> sp = m_SDKMemberObjs[0];
  67. m_SDKMemberObjs.RemoveAt(0);
  68. sp.p->Release();
  69. }
  70. }
  71. STDMETHOD(Activate)(BOOL bActive)
  72. {
  73. if(m_bActive != ((bActive) ? TRUE : FALSE))
  74. {
  75. m_bActive = ((bActive) ? TRUE : FALSE);
  76. _OnActivate(bActive ? true : false);
  77. }
  78. return S_OK;
  79. }
  80. STDMETHOD(SDKMemberAdded)(INmMember* pSDKMember)
  81. {
  82. HRESULT hr = S_FALSE;
  83. if(!_MemberInChannel(pSDKMember))
  84. {
  85. // Add the member
  86. pSDKMember->AddRef();
  87. m_SDKMemberObjs.Add(pSDKMember);
  88. // Notify the sinks
  89. Fire_MemberChanged(NM_MEMBER_ADDED, pSDKMember);
  90. hr = S_OK;
  91. }
  92. return hr;
  93. }
  94. STDMETHOD(SDKMemberRemoved)(INmMember* pSDKMember)
  95. {
  96. HRESULT hr = S_FALSE;
  97. for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  98. {
  99. CComPtr<INmMember> spMember = m_SDKMemberObjs[i];
  100. if(spMember.IsEqualObject(pSDKMember))
  101. {
  102. m_SDKMemberObjs.RemoveAt(i);
  103. Fire_MemberChanged(NM_MEMBER_REMOVED, spMember);
  104. spMember.p->Release();
  105. hr = S_OK;
  106. break;
  107. }
  108. }
  109. return hr;
  110. }
  111. STDMETHOD(SDKMemberChanged)(INmMember* pSDKMember)
  112. {
  113. return Fire_MemberChanged(NM_MEMBER_UPDATED, pSDKMember);
  114. }
  115. void NotifySinkOfMembers(INmChannelNotify* pNotify)
  116. {
  117. for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  118. {
  119. pNotify->MemberChanged(NM_MEMBER_ADDED, m_SDKMemberObjs[i]);
  120. }
  121. }
  122. STDMETHOD(FireNotificationsToSyncState)()
  123. {
  124. for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  125. {
  126. Fire_MemberChanged(NM_MEMBER_ADDED, m_SDKMemberObjs[i]);
  127. }
  128. return S_OK;
  129. }
  130. protected: // Helper Fns
  131. INmMember* _GetSDKMemberFromInternalMember(INmMember* pInternalMember);
  132. HRESULT _RemoveMember(INmMember* pInternalMember);
  133. virtual bool _MemberInChannel(INmMember* pSDKMember);
  134. private:
  135. CSimpleArray<INmMember*> m_SDKMemberObjs;
  136. CNmConferenceObj* m_pConfObj;
  137. BOOL m_bActive;
  138. };
  139. ///////////////////////////////////////////////////////////////////
  140. // INmChannel
  141. ///////////////////////////////////////////////////////////////////
  142. template<class T, const IID* piid, DWORD dwCh>
  143. STDMETHODIMP CNmChannel<T, piid, dwCh>::IsSameAs(INmChannel *pChannel)
  144. {
  145. DBGENTRY(CNmChannel::IsSameAs);
  146. HRESULT hr = E_NOTIMPL;
  147. CComPtr<IUnknown> pUnk(GetUnknown());
  148. hr = pUnk.IsEqualObject(pChannel) ? S_OK : S_FALSE;
  149. DBGEXIT_HR(CNmChannel::IsSameAs,hr);
  150. return hr;
  151. }
  152. template<class T, const IID* piid, DWORD dwCh>
  153. STDMETHODIMP CNmChannel<T, piid, dwCh>::IsActive(void)
  154. {
  155. DBGENTRY(CNmChannel::IsActive);
  156. HRESULT hr = _IsActive();
  157. DBGEXIT_HR(CNmChannel::IsActive,hr);
  158. return hr;
  159. }
  160. template<class T, const IID* piid, DWORD dwCh>
  161. STDMETHODIMP CNmChannel<T, piid, dwCh>::SetActive(BOOL fActive)
  162. {
  163. DBGENTRY(CNmChannel::SetActive);
  164. HRESULT hr = _SetActive(fActive);
  165. DBGEXIT_HR(CNmChannel::SetActive,hr);
  166. return hr;
  167. }
  168. template<class T, const IID* piid, DWORD dwCh>
  169. STDMETHODIMP CNmChannel<T, piid, dwCh>::GetConference(INmConference **ppConference)
  170. {
  171. DBGENTRY(CNmChannel::GetConference);
  172. HRESULT hr = S_OK;
  173. if(m_pConfObj)
  174. {
  175. IUnknown* pUnk = m_pConfObj->GetUnknown();
  176. if(pUnk)
  177. {
  178. hr = pUnk->QueryInterface(IID_INmConference,reinterpret_cast<void**>(ppConference));
  179. }
  180. else
  181. {
  182. hr = S_FALSE;
  183. }
  184. }
  185. DBGEXIT_HR(CNmChannel::GetConference,hr);
  186. return hr;
  187. }
  188. template<class T, const IID* piid, DWORD dwCh>
  189. STDMETHODIMP CNmChannel<T, piid, dwCh>::GetInterface(IID *_piid)
  190. {
  191. DBGENTRY(CNmChannel::GetInterface);
  192. HRESULT hr = S_OK;
  193. if(piid)
  194. {
  195. *_piid = *piid;
  196. }
  197. else
  198. {
  199. hr = E_POINTER;
  200. }
  201. DBGEXIT_HR(CNmChannel::GetInterface,hr);
  202. return hr;
  203. }
  204. template<class T, const IID* piid, DWORD dwCh>
  205. STDMETHODIMP CNmChannel<T, piid, dwCh>::GetNmch(ULONG *puCh)
  206. {
  207. DBGENTRY(CNmChannel::GetNmch);
  208. HRESULT hr = S_OK;
  209. if(puCh)
  210. {
  211. *puCh = dwCh;
  212. }
  213. else
  214. {
  215. hr = E_POINTER;
  216. }
  217. DBGEXIT_HR(CNmChannel::GetNmch,hr);
  218. return hr;
  219. }
  220. template<class T, const IID* piid, DWORD dwCh>
  221. STDMETHODIMP CNmChannel<T, piid, dwCh>::EnumMember(IEnumNmMember **ppEnum)
  222. {
  223. DBGENTRY(CNmChannel::EnumMember);
  224. HRESULT hr = S_OK;
  225. hr = CreateEnumFromSimpleAryOfInterface<IEnumNmMember, INmMember>(m_SDKMemberObjs, ppEnum);
  226. DBGEXIT_HR(CNmChannel::EnumMember,hr);
  227. return hr;
  228. }
  229. template<class T, const IID* piid, DWORD dwCh>
  230. STDMETHODIMP CNmChannel<T, piid, dwCh>::GetMemberCount(ULONG * puCount)
  231. {
  232. DBGENTRY(CNmChannel::GetMemberCount);
  233. HRESULT hr = S_OK;
  234. if(puCount)
  235. {
  236. *puCount = m_SDKMemberObjs.GetSize();
  237. }
  238. else
  239. {
  240. hr = E_POINTER;
  241. }
  242. DBGEXIT_HR(CNmChannel::GetMemberCount,hr);
  243. return hr;
  244. }
  245. ///////////////////////////////////////////////////////////////////
  246. // INmChannelNotify
  247. ///////////////////////////////////////////////////////////////////
  248. template<class T, const IID* piid, DWORD dwCh>
  249. STDMETHODIMP CNmChannel<T, piid, dwCh>::NmUI(CONFN uNotify)
  250. {
  251. DBGENTRY(CNmChannel::NmUI);
  252. HRESULT hr = S_OK;
  253. DBGEXIT_HR(CNmChannel::NmUI,hr);
  254. return hr;
  255. }
  256. template<class T, const IID* piid, DWORD dwCh>
  257. STDMETHODIMP CNmChannel<T, piid, dwCh>::MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pInternalMember)
  258. {
  259. DBGENTRY(CNmChannel::MemberChanged);
  260. HRESULT hr = S_OK;
  261. if(pInternalMember && m_pConfObj)
  262. {
  263. INmMember* pMember = NULL;
  264. if(NM_MEMBER_ADDED == uNotify)
  265. {
  266. // Only add it if we haven't added it yet
  267. if(!(pMember = _GetSDKMemberFromInternalMember(pInternalMember)))
  268. {
  269. pMember = m_pConfObj->GetSDKMemberFromInternalMember(pInternalMember);
  270. ASSERT(pMember);
  271. pMember->AddRef();
  272. m_SDKMemberObjs.Add(pMember);
  273. }
  274. else
  275. {
  276. // We already have this member
  277. goto end;
  278. }
  279. }
  280. if(!pMember)
  281. {
  282. pMember = _GetSDKMemberFromInternalMember(pInternalMember);
  283. }
  284. // It is possable that the member has already been removed..
  285. if(pMember)
  286. {
  287. if(NM_MEMBER_REMOVED == uNotify)
  288. {
  289. _RemoveMember(pInternalMember);
  290. }
  291. else
  292. {
  293. Fire_MemberChanged(uNotify, pMember);
  294. }
  295. }
  296. }
  297. else
  298. {
  299. ERROR_OUT(("The member is not in the conference yet!!!"));
  300. hr = E_UNEXPECTED;
  301. }
  302. end:
  303. DBGEXIT_HR(CNmChannel::MemberChanged,hr);
  304. return hr;
  305. }
  306. template<class T, const IID* piid, DWORD dwCh>
  307. INmMember* CNmChannel<T, piid, dwCh>::_GetSDKMemberFromInternalMember(INmMember* pInternalMember)
  308. {
  309. INmMember* pRet = NULL;
  310. for( int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  311. {
  312. CComQIPtr<IInternalMemberObj> spInternal = m_SDKMemberObjs[i];
  313. ASSERT(spInternal);
  314. CComPtr<INmMember> spMember;
  315. if(SUCCEEDED(spInternal->GetInternalINmMember(&spMember)))
  316. {
  317. if(spMember.IsEqualObject(pInternalMember))
  318. {
  319. pRet = m_SDKMemberObjs[i];
  320. break;
  321. }
  322. }
  323. }
  324. return pRet;
  325. }
  326. template<class T, const IID* piid, DWORD dwCh>
  327. HRESULT CNmChannel<T, piid, dwCh>::_RemoveMember(INmMember* pInternalMember)
  328. {
  329. HRESULT hr = E_FAIL;
  330. for( int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  331. {
  332. CComQIPtr<IInternalMemberObj> spSDKObj = m_SDKMemberObjs[i];
  333. CComPtr<INmMember> spSDKMember = m_SDKMemberObjs[i];
  334. ASSERT(spSDKObj);
  335. CComPtr<INmMember> spMember;
  336. if(SUCCEEDED(spSDKObj->GetInternalINmMember(&spMember)))
  337. {
  338. // Worst case we return S_FALSE to indicate that there is no such member
  339. hr = S_FALSE;
  340. if(spMember.IsEqualObject(pInternalMember))
  341. {
  342. m_SDKMemberObjs.RemoveAt(i);
  343. Fire_MemberChanged(NM_MEMBER_REMOVED, spSDKMember);
  344. spSDKMember.p->Release();
  345. hr = S_OK;
  346. break;
  347. }
  348. }
  349. }
  350. return hr;
  351. }
  352. template<class T, const IID* piid, DWORD dwCh>
  353. bool CNmChannel<T, piid, dwCh>::_MemberInChannel(INmMember* pSDKMember)
  354. {
  355. for( int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
  356. {
  357. CComPtr<INmMember> spMember = m_SDKMemberObjs[i];
  358. if(spMember.IsEqualObject(pSDKMember))
  359. {
  360. return true;
  361. }
  362. }
  363. return false;
  364. }
  365. #endif // __NmChannel_h__