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.

361 lines
8.3 KiB

  1. #include "precomp.h"
  2. //
  3. // H323UI.cpp
  4. //
  5. // ChrisPi
  6. //
  7. // Created: 03-04-96 (as audioui.cpp)
  8. // Renamed: 02-20-97
  9. //
  10. #include <mmreg.h>
  11. #include <mmsystem.h>
  12. #include "h323.h"
  13. #include <ih323cc.h>
  14. #include <mperror.h>
  15. PORT g_ListenPort; // port # that this app is listening on
  16. static const char g_cszCreateStreamProviderEP[] = _TEXT("CreateStreamProvider");
  17. // static member initialization:
  18. CH323UI* CH323UI::m_spH323UI = NULL;
  19. CH323UI::CH323UI() :
  20. m_pH323CallControl(NULL),
  21. m_pStreamProvider(NULL),
  22. m_pConnEvent(NULL),
  23. m_pConfAdvise(NULL),
  24. m_uCaps(0),
  25. m_uRef(1)
  26. {
  27. DebugEntry(CH323UI::CH323UI);
  28. if (NULL == CH323UI::m_spH323UI)
  29. {
  30. m_spH323UI = this;
  31. }
  32. else
  33. {
  34. ERROR_OUT(("CH323UI class can only be constructed once for now!"));
  35. }
  36. DebugExitVOID(CH323UI::CH323UI);
  37. }
  38. CH323UI::~CH323UI()
  39. {
  40. DebugEntry(CH323UI::~CH323UI);
  41. if (NULL != m_pH323CallControl)
  42. {
  43. m_pH323CallControl->Release();
  44. m_pH323CallControl = NULL;
  45. }
  46. if(NULL != m_pStreamProvider)
  47. {
  48. m_pStreamProvider->Release();
  49. m_pStreamProvider = NULL;
  50. }
  51. if (m_spH323UI == this)
  52. {
  53. m_spH323UI = NULL;
  54. }
  55. DebugExitVOID(CH323UI::~CH323UI);
  56. }
  57. ULONG CH323UI::AddRef()
  58. {
  59. m_uRef++;
  60. return m_uRef;
  61. }
  62. ULONG CH323UI::Release()
  63. {
  64. m_uRef--;
  65. if(m_uRef == 0)
  66. {
  67. delete this;
  68. return 0;
  69. }
  70. return m_uRef;
  71. }
  72. STDMETHODIMP CH323UI::QueryInterface( REFIID iid, void ** ppvObject)
  73. {
  74. HRESULT hr = E_NOINTERFACE;
  75. if(!ppvObject)
  76. return hr;
  77. *ppvObject = 0;
  78. if((iid == IID_IH323ConfAdvise)
  79. || (iid == IID_IUnknown))
  80. {
  81. *ppvObject = (IH323ConfAdvise *)this;
  82. hr = hrSuccess;
  83. AddRef();
  84. }
  85. return (hr);
  86. }
  87. STDMETHODIMP CH323UI::GetMediaChannel (GUID *pmediaID,
  88. BOOL bSendDirection, IMediaChannel **ppI)
  89. {
  90. ASSERT(m_pStreamProvider);
  91. // delegate to the appropriate stream provider. For the time being
  92. // there is only one provider that does both audio & video
  93. // the assignment of media streams to channels should be under control of this
  94. // (CH323UI) module and the related (i.e. CVideoPump) objects. There is no
  95. // current way to for CH323UI to tell CVideoPump what the media stream interface
  96. // pointer is, but the underlying CommChannel (CVideoPump::m_pCommChannel) has to
  97. // remember this assignment for other reasons. For the time being, let CVideoPump
  98. // get the assigned media stream from the CommChannel.
  99. return (::GetConfObject())->GetMediaChannel(pmediaID,
  100. bSendDirection, ppI);
  101. }
  102. HRESULT CH323UI::Init(HWND hwnd, HINSTANCE hInstance, UINT uCaps,
  103. CH323ConnEvent *pConnEvent, IH323ConfAdvise *pConfAdvise)
  104. {
  105. DebugEntry(CH323UI::Init);
  106. HINSTANCE hLibH323CC = NULL;
  107. HINSTANCE hLibStream = NULL;
  108. CREATEH323CC pfnCreateH323CC = NULL;
  109. CREATE_SP pfnCreateStreamProvider =NULL;
  110. HRESULT hr = E_FAIL;
  111. ASSERT(uCaps & CAPFLAG_H323_CC);
  112. m_uCaps = uCaps;
  113. ASSERT(NULL == m_pH323CallControl);
  114. //
  115. // Initialize H323 call control
  116. //
  117. hLibH323CC = NmLoadLibrary(H323DLL,FALSE);
  118. if (hLibH323CC == NULL)
  119. {
  120. WARNING_OUT(("NmLoadLibrary(H323DLL) failed"));
  121. hr = GetLastHR();
  122. goto MyExit;
  123. }
  124. pfnCreateH323CC = (CREATEH323CC) ::GetProcAddress(hLibH323CC, SZ_FNCREATEH323CC);
  125. if (pfnCreateH323CC == NULL)
  126. {
  127. ERROR_OUT(("GetProcAddress(CreateH323CC) failed"));
  128. hr = GetLastHR();
  129. goto MyExit;
  130. }
  131. hr = pfnCreateH323CC(&m_pH323CallControl, TRUE, uCaps);
  132. if (FAILED(hr))
  133. {
  134. ERROR_OUT(("CreateH323CC failed, hr=0x%lx", hr));
  135. goto MyExit;
  136. }
  137. hr = m_pH323CallControl->Initialize(&g_ListenPort);
  138. if (FAILED(hr))
  139. {
  140. // Made this a warning because it is common (occurs on all machines
  141. // without sound cards)
  142. WARNING_OUT(("H323CallControlInitialize failed, hr=0x%lx", hr));
  143. goto MyExit;
  144. }
  145. //
  146. // If H323 AV streaming is allowed, initialize that too.
  147. //
  148. if (uCaps & CAPFLAGS_AV_STREAMS)
  149. {
  150. hLibStream = NmLoadLibrary(NACDLL,FALSE);
  151. if (hLibStream == NULL)
  152. {
  153. WARNING_OUT(("NmLoadLibrary(NACDLL) failed"));
  154. hr = GetLastHR();
  155. goto MyExit;
  156. }
  157. pfnCreateStreamProvider = (CREATE_SP) ::GetProcAddress(hLibStream, g_cszCreateStreamProviderEP);
  158. if (pfnCreateStreamProvider == NULL)
  159. {
  160. ERROR_OUT(("GetProcAddress(CreateStreamProvider) failed"));
  161. hr = GetLastHR();
  162. goto MyExit;
  163. }
  164. hr = pfnCreateStreamProvider(&m_pStreamProvider);
  165. if (FAILED(hr))
  166. {
  167. ERROR_OUT(("CreateStreamProvider failed, hr=0x%lx", hr));
  168. goto MyExit;
  169. }
  170. hr = m_pStreamProvider->Initialize(hwnd, hInstance);
  171. if (FAILED(hr))
  172. {
  173. // Made this a warning because it is common (occurs on all machines
  174. // without sound cards)
  175. WARNING_OUT(("m_pStreamProvider ->Initialize failed, hr=0x%lx", hr));
  176. goto MyExit;
  177. }
  178. }
  179. hr = m_pH323CallControl->RegisterConnectionNotify(CH323UI::ConnectionNotify);
  180. if (FAILED(hr))
  181. {
  182. ERROR_OUT(("RegisterConnectionNotify failed, hr=0x%lx", hr));
  183. goto MyExit;
  184. }
  185. // store the callback interfaces
  186. m_pConnEvent = pConnEvent;
  187. m_pConfAdvise = pConfAdvise;
  188. MyExit:
  189. if (FAILED(hr))
  190. {
  191. if(NULL != m_pStreamProvider)
  192. {
  193. m_pStreamProvider->Release();
  194. m_pStreamProvider = NULL;
  195. }
  196. if(NULL != m_pH323CallControl)
  197. {
  198. // If there was an error during init, ensure that the nac
  199. // object is released and the pointer is set to NULL
  200. m_pH323CallControl->Release();
  201. m_pH323CallControl = NULL;
  202. }
  203. }
  204. DebugExitULONG(CH323UI::Init, hr);
  205. return hr;
  206. }
  207. CREQ_RESPONSETYPE CH323UI::_ConnectionNotify( IH323Endpoint* pConn,
  208. P_APP_CALL_SETUP_DATA lpvMNMData)
  209. {
  210. CREQ_RESPONSETYPE resp = CRR_REJECT;
  211. HRESULT hr;
  212. ASSERT(m_pConfAdvise);
  213. hr = pConn->SetAdviseInterface (m_pConfAdvise);
  214. if (FAILED(hr))
  215. {
  216. ERROR_OUT(("ConnectionNotify: couldn't SetAdviseInterface, hr=0x%lx\r", hr));
  217. }
  218. if (NULL != m_pConnEvent)
  219. {
  220. resp = m_pConnEvent->OnH323IncomingCall(pConn, lpvMNMData);
  221. }
  222. // BUGBUG: the caller is assuming that the callee will be doing the release
  223. // this should be changed so that the caller does the release
  224. pConn->Release();
  225. return resp;
  226. }
  227. CREQ_RESPONSETYPE CALLBACK CH323UI::ConnectionNotify( IH323Endpoint* pConn,
  228. P_APP_CALL_SETUP_DATA lpvMNMData)
  229. {
  230. DebugEntry(CH323UI::ConnectionNotify);
  231. CREQ_RESPONSETYPE resp = CRR_REJECT;
  232. if (pConn == NULL)
  233. {
  234. ERROR_OUT(("ConnectionNotify called with NULL pConn!"));
  235. }
  236. else
  237. {
  238. ASSERT(m_spH323UI);
  239. resp = m_spH323UI->_ConnectionNotify(pConn, lpvMNMData);
  240. }
  241. DebugExitINT(CH323UI::ConnectionNotify, resp);
  242. return resp;
  243. }
  244. VOID CH323UI::SetCaptureDevice(DWORD dwCaptureID)
  245. {
  246. // Select the proper capture device
  247. HRESULT hr;
  248. IVideoDevice *pVideoDevice = NULL;
  249. if (m_pStreamProvider)
  250. {
  251. hr = m_pStreamProvider->QueryInterface(IID_IVideoDevice, (void **)&pVideoDevice);
  252. if(FAILED(hr))
  253. {
  254. ERROR_OUT(("CH323UI::SetCaptureDevice failed"));
  255. return;
  256. }
  257. if(pVideoDevice)
  258. {
  259. pVideoDevice->SetCurrCapDevID(dwCaptureID);
  260. pVideoDevice->Release();
  261. }
  262. }
  263. }
  264. VOID CH323UI::SetBandwidth(DWORD dwBandwidth)
  265. {
  266. HRESULT hr = m_pH323CallControl->SetMaxPPBandwidth(dwBandwidth);
  267. ASSERT(SUCCEEDED(hr));
  268. }
  269. // This (SetUserName) is not really sufficient for H.323 calls and gatekeeper
  270. // registration. 2 items are needed (display name, H.323 ID)
  271. // And a third is optional. (users phone number in E.164 form).
  272. // This hack takes the single display name and sets BOTH the H323ID and user
  273. // display name.
  274. VOID CH323UI::SetUserName(BSTR bstrName)
  275. {
  276. HRESULT hr;
  277. ASSERT(bstrName);
  278. H323ALIASLIST AliasList;
  279. H323ALIASNAME AliasName;
  280. AliasName.aType = AT_H323_ID;
  281. AliasList.wCount = 1;
  282. AliasList.pItems = &AliasName;
  283. AliasName.lpwData = bstrName;
  284. AliasName.wDataLength = (WORD)SysStringLen(bstrName);// # of unicode chars, w/o NULL terminator
  285. hr = m_pH323CallControl->SetUserAliasNames(&AliasList);
  286. ASSERT(SUCCEEDED(hr));
  287. hr = m_pH323CallControl->SetUserDisplayName(AliasName.lpwData);
  288. ASSERT(SUCCEEDED(hr));
  289. }
  290. IMediaChannelBuilder* CH323UI::GetStreamProvider()
  291. {
  292. if (m_pStreamProvider)
  293. {
  294. m_pStreamProvider->AddRef();
  295. }
  296. return m_pStreamProvider;
  297. }
  298.