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.

397 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. wavecall.cpp
  5. Abstract:
  6. This module contains implementation of CWaveMSPCall.
  7. Author:
  8. Zoltan Szilagyi (zoltans) September 7, 1998
  9. --*/
  10. #include "stdafx.h"
  11. #include <commctrl.h> // ONLY to compile unimdmp.h
  12. #include <setupapi.h> // ONLY to compile unimdmp.h
  13. #include <unimdmp.h>
  14. ///////////////////////////////////////////////////////////////////////////////
  15. ///////////////////////////////////////////////////////////////////////////////
  16. //
  17. CWaveMSPCall::CWaveMSPCall() : CMSPCallMultiGraph()
  18. {
  19. LOG((MSP_TRACE, "CWaveMSPCall::CWaveMSPCall entered."));
  20. LOG((MSP_TRACE, "CWaveMSPCall::CWaveMSPCall exited."));
  21. }
  22. ///////////////////////////////////////////////////////////////////////////////
  23. ///////////////////////////////////////////////////////////////////////////////
  24. //
  25. CWaveMSPCall::~CWaveMSPCall()
  26. {
  27. LOG((MSP_TRACE, "CWaveMSPCall::~CWaveMSPCall entered."));
  28. LOG((MSP_TRACE, "CWaveMSPCall::~CWaveMSPCall exited."));
  29. }
  30. ULONG CWaveMSPCall::MSPCallAddRef(void)
  31. {
  32. return MSPAddRefHelper(this);
  33. }
  34. ULONG CWaveMSPCall::MSPCallRelease(void)
  35. {
  36. return MSPReleaseHelper(this);
  37. }
  38. ///////////////////////////////////////////////////////////////////////////////
  39. ///////////////////////////////////////////////////////////////////////////////
  40. //
  41. HRESULT CWaveMSPCall::Init(
  42. IN CMSPAddress * pMSPAddress,
  43. IN MSP_HANDLE htCall,
  44. IN DWORD dwReserved,
  45. IN DWORD dwMediaType
  46. )
  47. {
  48. // No need to acquire locks on this call because it is called only
  49. // once when the object is created. No other calls can be made on
  50. // this object at this point.
  51. LOG((MSP_TRACE, "CWaveMSPCall::Init - enter"));
  52. //
  53. // First do the base class method. We are adding to the functionality,
  54. // not replacing it.
  55. //
  56. HRESULT hr;
  57. hr = CMSPCallMultiGraph::Init(pMSPAddress,
  58. htCall,
  59. dwReserved,
  60. dwMediaType);
  61. if (FAILED(hr))
  62. {
  63. LOG((MSP_ERROR, "CWaveMSPCall::Init - "
  64. "base class method failed: %x", hr));
  65. return hr;
  66. }
  67. //
  68. // Our calls always come with two streams. Create them now. Use the base class
  69. // methods, as our overriden methods (exposed to the user) purposely fail in order
  70. // to keep the user from creating or removing streams themselves.
  71. // These methods return a pointer to the ITStream. They get saved in our list of
  72. // ITStreams, and we also save them here as CWaveMSPStream pointers.
  73. //
  74. ITStream * pStream;
  75. //
  76. // Create the capture stream.
  77. //
  78. hr = InternalCreateStream (dwMediaType,
  79. TD_CAPTURE,
  80. &pStream);
  81. if (FAILED(hr))
  82. {
  83. LOG((MSP_ERROR, "CWaveMSPCall::Init - "
  84. "couldn't create capture stream: %x", hr));
  85. return hr;
  86. }
  87. m_pCaptureStream = dynamic_cast<CWaveMSPStream *> (pStream);
  88. if ( m_pCaptureStream == NULL )
  89. {
  90. LOG((MSP_ERROR, "CWaveMSPCall::Init - "
  91. "couldn't dynamic_cast capture stream - exit E_FAIL"));
  92. return E_FAIL;
  93. }
  94. pStream->Release();
  95. //
  96. // Create the render stream.
  97. //
  98. hr = InternalCreateStream (dwMediaType,
  99. TD_RENDER,
  100. &pStream);
  101. if (FAILED(hr))
  102. {
  103. LOG((MSP_ERROR, "CWaveMSPCall::Init - "
  104. "couldn't create capture stream: %x", hr));
  105. return hr;
  106. }
  107. m_pRenderStream = dynamic_cast<CWaveMSPStream *> (pStream);
  108. if ( m_pRenderStream == NULL )
  109. {
  110. LOG((MSP_ERROR, "CWaveMSPCall::Init - "
  111. "couldn't dynamic_cast render stream - exit E_FAIL"));
  112. return E_FAIL;
  113. }
  114. pStream->Release();
  115. LOG((MSP_TRACE, "CWaveMSPCall::Init - exit S_OK"));
  116. return S_OK;
  117. }
  118. ///////////////////////////////////////////////////////////////////////////////
  119. ///////////////////////////////////////////////////////////////////////////////
  120. //
  121. // We override this to make sure the number of
  122. // streams we have is constant.
  123. //
  124. STDMETHODIMP CWaveMSPCall::CreateStream (
  125. IN long lMediaType,
  126. IN TERMINAL_DIRECTION Direction,
  127. IN OUT ITStream ** ppStream
  128. )
  129. {
  130. LOG((MSP_TRACE, "CWaveMSPCall::CreateStream entered."));
  131. LOG((MSP_TRACE, "CWaveMSPCall::CreateStream - "
  132. "we have a fixed set of streams - exit TAPI_E_MAXSTREAMS"));
  133. return TAPI_E_MAXSTREAMS;
  134. }
  135. ///////////////////////////////////////////////////////////////////////////////
  136. ///////////////////////////////////////////////////////////////////////////////
  137. //
  138. // We override this to make sure the number of
  139. // streams we have is constant.
  140. //
  141. STDMETHODIMP CWaveMSPCall::RemoveStream (
  142. IN ITStream * pStream
  143. )
  144. {
  145. LOG((MSP_TRACE, "CWaveMSPCall::RemoveStream entered."));
  146. LOG((MSP_TRACE, "CWaveMSPCall::RemoveStream - "
  147. "we have a fixed set of streams - exit TAPI_E_NOTSUPPORTED"));
  148. return TAPI_E_NOTSUPPORTED;
  149. }
  150. ///////////////////////////////////////////////////////////////////////////////
  151. ///////////////////////////////////////////////////////////////////////////////
  152. //
  153. // This is our override to create the right kind of stream on stream creation.
  154. // The base class checks the arguments for us.
  155. //
  156. HRESULT CWaveMSPCall::CreateStreamObject(
  157. IN DWORD dwMediaType,
  158. IN TERMINAL_DIRECTION Direction,
  159. IN IMediaEvent * pGraph,
  160. IN ITStream ** ppStream
  161. )
  162. {
  163. LOG((MSP_TRACE, "CWaveMSPCall::CreateStreamObject - enter"));
  164. HRESULT hr;
  165. CMSPComObject<CWaveMSPStream> * pStream;
  166. hr = CMSPComObject<CWaveMSPStream>::CreateInstance( &pStream );
  167. if ( FAILED(hr) )
  168. {
  169. LOG((MSP_ERROR, "CWaveMSPCall::CreateStreamObject - "
  170. "can't create stream object - 0x%08x", hr));
  171. return hr;
  172. }
  173. hr = pStream->_InternalQueryInterface( IID_ITStream,
  174. (void **) ppStream );
  175. if ( FAILED(hr) )
  176. {
  177. LOG((MSP_ERROR, "CWaveMSPCall::CreateStreamObject - "
  178. "can't get ITStream interface - 0x%08x", hr));
  179. delete pStream;
  180. return hr;
  181. }
  182. hr = pStream->Init( (MSP_HANDLE) m_pMSPAddress,
  183. this,
  184. pGraph,
  185. dwMediaType,
  186. Direction);
  187. if ( FAILED(hr) )
  188. {
  189. LOG((MSP_ERROR, "CWaveMSPCall::CreateStreamObject - "
  190. "can't Init stream object - 0x%08x", hr));
  191. (*ppStream)->Release();
  192. return hr;
  193. }
  194. LOG((MSP_TRACE, "CWaveMSPCall::CreateStreamObject - exit S_OK"));
  195. return S_OK;
  196. }
  197. ///////////////////////////////////////////////////////////////////////////////
  198. ///////////////////////////////////////////////////////////////////////////////
  199. //
  200. // First DWORD = Command Second DWORD Third DWORD
  201. // 0 Set wave IDs WaveIn ID WaveOut ID
  202. // 1 Start streaming <ignored> <ignored>
  203. // 2 Stop streaming <ignored> <ignored>
  204. //
  205. // The method returns S_OK even if an individual stream failed to
  206. // start, stop, or initialize. This is because TAPI 3.0 doesn't need to
  207. // know about streaming failures in this code path. Instead, we should
  208. // generate events to note failures.
  209. //
  210. HRESULT CWaveMSPCall::ReceiveTSPCallData(
  211. IN PBYTE pBuffer,
  212. IN DWORD dwSize
  213. )
  214. {
  215. CSATSPMSPBLOB *Blob=(CSATSPMSPBLOB*)pBuffer;
  216. LOG((MSP_TRACE, "CWaveMSPCall::ReceiveTSPCallData - enter"));
  217. //
  218. // Check that the buffer is as big as advertised.
  219. //
  220. if ( IsBadReadPtr(pBuffer, sizeof(BYTE) * dwSize) )
  221. {
  222. LOG((MSP_ERROR, "CWaveMSPCall::ReceiveTSPCallData - "
  223. "bad buffer - exit E_POINTER"));
  224. return E_POINTER;
  225. }
  226. //
  227. // Check if we have a command DWORD.
  228. //
  229. if ( dwSize < sizeof(CSATSPMSPBLOB) ) {
  230. LOG((MSP_ERROR, "CWaveMSPCall::ReceiveTSPCallData - "
  231. "need a DWORD for command - exit E_INVALIDARG"));
  232. return E_INVALIDARG;
  233. }
  234. //
  235. // We are going to access the streams lists -- grab the lock
  236. //
  237. CLock lock(m_lock);
  238. _ASSERTE( m_Streams.GetSize() == 2 );
  239. int i;
  240. HRESULT hr;
  241. //
  242. // Based on the command, take action:
  243. //
  244. switch ( Blob->dwCmd )
  245. {
  246. case CSATSPMSPCMD_CONNECTED:
  247. {
  248. LOG((MSP_INFO, "CWaveMSPCall::ReceiveTSPCallData - "
  249. "setting WaveInID=%d, WaveOutID=%d",
  250. ((DWORD *) pBuffer) [1],
  251. ((DWORD *) pBuffer) [2]));
  252. //
  253. // Use our saved class pointers to access the private method,
  254. // and also to conveniently differentiate between render and
  255. // capture. Note that the capture stream is the one with a
  256. // capture terminal, and thus we need to give it the wave out id,
  257. // and we need to give the render terminal the wave in ID.
  258. //
  259. hr = m_pRenderStream ->SetWaveID( &Blob->PermanentGuid ); // wavein
  260. if ( FAILED(hr) )
  261. {
  262. LOG((MSP_ERROR, "CWaveMSPCall::ReceiveTSPCallData - "
  263. "render stream SetWaveID failed 0x%08x - "
  264. "firing CALL_STREAM_FAIL", hr));
  265. m_pRenderStream->FireEvent(CALL_STREAM_FAIL, hr, CALL_CAUSE_UNKNOWN);
  266. }
  267. hr = m_pCaptureStream->SetWaveID( &Blob->PermanentGuid ); // waveout
  268. if ( FAILED(hr) )
  269. {
  270. LOG((MSP_ERROR, "CWaveMSPCall::ReceiveTSPCallData - "
  271. "capture stream SetWaveID failed 0x%08x - "
  272. "firing CALL_STREAM_FAIL", hr));
  273. m_pCaptureStream->FireEvent(CALL_STREAM_FAIL, hr, CALL_CAUSE_UNKNOWN);
  274. }
  275. }
  276. // break;
  277. //
  278. // case 1: // start streaming
  279. {
  280. for ( i = 0; i < m_Streams.GetSize(); i++ )
  281. {
  282. hr = m_Streams[i]->StartStream();
  283. }
  284. }
  285. break;
  286. case CSATSPMSPCMD_DISCONNECTED:
  287. {
  288. for ( i = 0; i < m_Streams.GetSize(); i++ )
  289. {
  290. hr = m_Streams[i]->StopStream();
  291. }
  292. }
  293. break;
  294. default:
  295. LOG((MSP_ERROR, "CWaveMSPCall::ReceiveTSPCallData - "
  296. "invalid command - exit E_INVALIDARG"));
  297. return E_INVALIDARG;
  298. }
  299. LOG((MSP_TRACE, "CWaveMSPCall::ReceiveTSPCallData - exit S_OK"));
  300. return S_OK;
  301. }
  302. // eof