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.

1474 lines
33 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. phonemsp.cpp
  5. Abstract:
  6. Implements an MSP object for addresses that have phone terminals
  7. this makes the MSP abstraction in the address object much easier,
  8. since there will be no special cases for phone devices/terminals
  9. Author:
  10. mquinton - 9/24/98
  11. Notes:
  12. Revision History:
  13. --*/
  14. #include "stdafx.h"
  15. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  16. //
  17. // CPhoneMSP::Initialize
  18. //
  19. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  20. STDMETHODIMP
  21. CPhoneMSP::Initialize(
  22. MSP_HANDLE hEvent
  23. )
  24. {
  25. HRESULT hr = S_OK;
  26. LOG((TL_TRACE, "Initialize - enter"));
  27. Lock();
  28. m_hEvent = (HANDLE)hEvent;
  29. #if DBG
  30. m_pDebug = (PWSTR) ClientAlloc( 1 );
  31. #endif
  32. Unlock();
  33. LOG((TL_TRACE, "Initialize - exit - return %lx", hr));
  34. return hr;
  35. }
  36. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  37. //
  38. // CPhoneMSP::Shutdown
  39. //
  40. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  41. STDMETHODIMP
  42. CPhoneMSP::Shutdown()
  43. {
  44. HRESULT hr = E_NOTIMPL;
  45. LOG((TL_TRACE, "Shutdown - enter"));
  46. LOG((TL_TRACE, "Shutdown - exit - return %lx", hr));
  47. return hr;
  48. }
  49. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  50. //
  51. // CPhoneMSP::CreateMSPCall
  52. //
  53. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  54. STDMETHODIMP
  55. CPhoneMSP::CreateMSPCall(
  56. MSP_HANDLE hCall,
  57. DWORD dwReserved,
  58. DWORD dwMediaType,
  59. IUnknown * pOuterUnknown,
  60. IUnknown ** ppStreamControl
  61. )
  62. {
  63. HRESULT hr;
  64. CComAggObject<CPhoneMSPCall> * pPhoneMSPCall;
  65. ITPhoneMSPCallPrivate * pPhoneMSPCallPrivate;
  66. LOG((TL_TRACE, "CreateMSPCall - enter"));
  67. pPhoneMSPCall = new CComAggObject<CPhoneMSPCall>(pOuterUnknown);
  68. if ( NULL == pPhoneMSPCall )
  69. {
  70. }
  71. //
  72. // save the aggregated interface in
  73. // the msppointer
  74. //
  75. pPhoneMSPCall->QueryInterface(
  76. IID_IUnknown,
  77. (void **)ppStreamControl
  78. );
  79. //
  80. // get to the real object
  81. //
  82. hr = (*ppStreamControl)->QueryInterface(
  83. IID_ITPhoneMSPCallPrivate,
  84. (void **)&pPhoneMSPCallPrivate
  85. );
  86. //
  87. // initialize it
  88. //
  89. hr = pPhoneMSPCallPrivate->Initialize( this );
  90. Lock();
  91. AddCall( *ppStreamControl );
  92. Unlock();
  93. pPhoneMSPCallPrivate->Release();
  94. LOG((TL_TRACE, "CreateMSPCall - exit - return %lx", hr));
  95. return hr;
  96. }
  97. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  98. //
  99. // CPhoneMSP::ShutdownMSPCall
  100. //
  101. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  102. STDMETHODIMP
  103. CPhoneMSP::ShutdownMSPCall(
  104. IUnknown * pStreamControl
  105. )
  106. {
  107. HRESULT hr = S_OK;
  108. LOG((TL_TRACE, "ShutdownMSPCall - enter"));
  109. Lock();
  110. RemoveCall( pStreamControl );
  111. Unlock();
  112. LOG((TL_TRACE, "ShutdownMSPCall - exit - return %lx", hr));
  113. return hr;
  114. }
  115. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  116. //
  117. // CPhoneMSP::ReceiveTSPData
  118. //
  119. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  120. STDMETHODIMP
  121. CPhoneMSP::ReceiveTSPData(
  122. IUnknown * pMSPCall,
  123. BYTE * pBuffer,
  124. DWORD dwSize
  125. )
  126. {
  127. HRESULT hr = S_OK;
  128. DWORD dwCommand;
  129. ITPhoneMSPCallPrivate * pCall;
  130. LOG((TL_TRACE, "ReceiveTSPData - enter"));
  131. if ( NULL == pMSPCall )
  132. {
  133. LOG((TL_ERROR, "ReceiveTSPData - null call"));
  134. return E_INVALIDARG;
  135. }
  136. dwCommand = *((LPDWORD)(pBuffer));
  137. hr = pMSPCall->QueryInterface(
  138. IID_ITPhoneMSPCallPrivate,
  139. (void**)&pCall
  140. );
  141. if ( !SUCCEEDED(hr) )
  142. {
  143. LOG((TL_ERROR, "ReceiveTSPData - bad call"));
  144. return E_FAIL;
  145. }
  146. LOG((TL_INFO, "ReceiveTSPData - command %d", dwCommand));
  147. switch (dwCommand)
  148. {
  149. case 1: // Start Streaming
  150. hr = pCall->OnConnect();
  151. break;
  152. case 2: // Stop Streaming
  153. hr = pCall->OnDisconnect();
  154. break;
  155. default:
  156. LOG((TL_ERROR, "ReceiveTSPData - invalid command "));
  157. hr = E_FAIL;
  158. break;
  159. }
  160. pCall->Release();
  161. LOG((TL_TRACE, "ReceiveTSPData - exit - return %lx", hr));
  162. return hr;
  163. }
  164. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  165. //
  166. // CPhoneMSP::GetEvent
  167. //
  168. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  169. STDMETHODIMP
  170. CPhoneMSP::GetEvent(
  171. DWORD * pdwSize,
  172. byte * pEventBuffer
  173. )
  174. {
  175. HRESULT hr = E_NOTIMPL;
  176. LOG((TL_TRACE, "GetEvent - enter"));
  177. LOG((TL_TRACE, "GetEvent - exit - return %lx", hr));
  178. return hr;
  179. }
  180. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  181. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  182. HRESULT
  183. CPhoneMSP::InitializeTerminals(
  184. HPHONEAPP hPhoneApp,
  185. DWORD dwAPIVersion,
  186. DWORD dwPhoneDevice,
  187. CAddress * pAddress
  188. )
  189. {
  190. LPPHONECAPS pPhoneCaps = NULL;
  191. HRESULT hr;
  192. BOOL bSucceeded = FALSE;
  193. ITStream * pStream;
  194. LOG((TL_TRACE, "InitializeTerminals - enter"));
  195. //
  196. // get the phone caps
  197. //
  198. hr = PhoneGetDevCapsWithAlloc(
  199. hPhoneApp,
  200. dwPhoneDevice,
  201. dwAPIVersion,
  202. &pPhoneCaps
  203. );
  204. if (S_OK != hr)
  205. {
  206. if (NULL != pPhoneCaps)
  207. {
  208. ClientFree( pPhoneCaps );
  209. }
  210. LOG((TL_ERROR, "CreatePhoneTerminals - PhoneGetDevCaps failed - %lx", hr ));
  211. return hr;
  212. }
  213. //
  214. // check the hook switch devs
  215. //
  216. if (0 == pPhoneCaps->dwHookSwitchDevs)
  217. {
  218. LOG((TL_ERROR, "CreatePhoneTerminal - no hook switch devs!" ));
  219. ClientFree( pPhoneCaps );
  220. return E_UNEXPECTED;
  221. }
  222. //
  223. // create terminal devices for each hook switch dev
  224. // need to create an audio in and audio out terminal
  225. // for each
  226. //
  227. ITTerminal * pTerminal;
  228. if (pPhoneCaps->dwHookSwitchDevs & PHONEHOOKSWITCHDEV_HANDSET)
  229. {
  230. hr = CTerminal::Create(
  231. hPhoneApp,
  232. dwPhoneDevice,
  233. pPhoneCaps,
  234. PHONEHOOKSWITCHDEV_HANDSET,
  235. TD_RENDER,
  236. dwAPIVersion,
  237. &pTerminal
  238. );
  239. if (SUCCEEDED(hr))
  240. {
  241. bSucceeded = TRUE;
  242. AddTerminal( pTerminal );
  243. pTerminal->Release();
  244. }
  245. hr = CTerminal::Create(
  246. hPhoneApp,
  247. dwPhoneDevice,
  248. pPhoneCaps,
  249. PHONEHOOKSWITCHDEV_HANDSET,
  250. TD_CAPTURE,
  251. dwAPIVersion,
  252. &pTerminal
  253. );
  254. if (SUCCEEDED(hr))
  255. {
  256. bSucceeded = TRUE;
  257. AddTerminal( pTerminal );
  258. pTerminal->Release();
  259. }
  260. }
  261. if (pPhoneCaps->dwHookSwitchDevs & PHONEHOOKSWITCHDEV_HEADSET)
  262. {
  263. hr = CTerminal::Create(
  264. hPhoneApp,
  265. dwPhoneDevice,
  266. pPhoneCaps,
  267. PHONEHOOKSWITCHDEV_HEADSET,
  268. TD_RENDER,
  269. dwAPIVersion,
  270. &pTerminal
  271. );
  272. if (SUCCEEDED(hr))
  273. {
  274. bSucceeded = TRUE;
  275. AddTerminal( pTerminal );
  276. pTerminal->Release();
  277. }
  278. hr = CTerminal::Create(
  279. hPhoneApp,
  280. dwPhoneDevice,
  281. pPhoneCaps,
  282. PHONEHOOKSWITCHDEV_HEADSET,
  283. TD_CAPTURE,
  284. dwAPIVersion,
  285. &pTerminal
  286. );
  287. if (SUCCEEDED(hr))
  288. {
  289. bSucceeded = TRUE;
  290. AddTerminal( pTerminal );
  291. pTerminal->Release();
  292. }
  293. }
  294. if (pPhoneCaps->dwHookSwitchDevs & PHONEHOOKSWITCHDEV_SPEAKER)
  295. {
  296. hr = CTerminal::Create(
  297. hPhoneApp,
  298. dwPhoneDevice,
  299. pPhoneCaps,
  300. PHONEHOOKSWITCHDEV_SPEAKER,
  301. TD_RENDER,
  302. dwAPIVersion,
  303. &pTerminal
  304. );
  305. if (SUCCEEDED(hr))
  306. {
  307. bSucceeded = TRUE;
  308. AddTerminal( pTerminal );
  309. pTerminal->Release();
  310. }
  311. hr = CTerminal::Create(
  312. hPhoneApp,
  313. dwPhoneDevice,
  314. pPhoneCaps,
  315. PHONEHOOKSWITCHDEV_SPEAKER,
  316. TD_CAPTURE,
  317. dwAPIVersion,
  318. &pTerminal
  319. );
  320. if (SUCCEEDED(hr))
  321. {
  322. bSucceeded = TRUE;
  323. AddTerminal( pTerminal );
  324. pTerminal->Release();
  325. }
  326. }
  327. //
  328. // free memory
  329. //
  330. if (NULL != pPhoneCaps)
  331. {
  332. ClientFree( pPhoneCaps );
  333. }
  334. if ( !bSucceeded )
  335. {
  336. LOG((TL_WARN, "No phone terminals created"));
  337. return E_FAIL;
  338. }
  339. LOG((TL_TRACE, "InitializeTerminals - exit"));
  340. return S_OK;
  341. }
  342. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  343. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  344. HRESULT
  345. CPhoneMSP::VerifyTerminal( ITTerminal * pTerminal )
  346. {
  347. int iReturn;
  348. Lock();
  349. iReturn = m_TerminalArray.Find( pTerminal );
  350. Unlock();
  351. if ( -1 == iReturn )
  352. {
  353. return TAPI_E_INVALIDTERMINAL;
  354. }
  355. return S_OK;
  356. }
  357. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  358. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  359. void
  360. CPhoneMSP::AddTerminal( ITTerminal * pTerminal )
  361. {
  362. Lock();
  363. m_TerminalArray.Add( pTerminal );
  364. Unlock();
  365. }
  366. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  367. //
  368. // called in lock
  369. //
  370. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  371. void
  372. CPhoneMSP::AddCall( IUnknown * pCall )
  373. {
  374. m_CallArray.Add( pCall );
  375. }
  376. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  377. //
  378. // called in lock
  379. //
  380. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  381. void
  382. CPhoneMSP::RemoveCall( IUnknown * pCall )
  383. {
  384. m_CallArray.Remove( pCall );
  385. }
  386. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  387. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  388. void
  389. CPhoneMSP::FinalRelease()
  390. {
  391. LOG((TL_TRACE, "FinalRelease - enter"));
  392. #if DBG
  393. ClientFree( m_pDebug );
  394. #endif
  395. m_TerminalArray.Shutdown();
  396. m_CallArray.Shutdown();
  397. LOG((TL_TRACE, "FinalRelease - exit"));
  398. }
  399. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  400. //
  401. // CPhoneMSP::get_StaticTerminals
  402. //
  403. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  404. STDMETHODIMP
  405. CPhoneMSP::get_StaticTerminals(
  406. VARIANT * pVariant
  407. )
  408. {
  409. HRESULT hr = S_OK;
  410. IDispatch * pDisp;
  411. LOG((TL_TRACE, "get_StaticTerminals - enter"));
  412. if (TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) )
  413. {
  414. LOG((TL_ERROR, "get_StaticTerminals - bad pointer"));
  415. return E_POINTER;
  416. }
  417. CComObject< CTapiCollection< ITTerminal > > * p;
  418. CComObject< CTapiCollection< ITTerminal > >::CreateInstance( &p );
  419. if (NULL == p)
  420. {
  421. LOG((TL_ERROR, "get_StaticTerminals - could not create collection" ));
  422. return E_OUTOFMEMORY;
  423. }
  424. Lock();
  425. // initialize
  426. hr = p->Initialize( m_TerminalArray );
  427. Unlock();
  428. if (S_OK != hr)
  429. {
  430. LOG((TL_ERROR, "get_StaticTerminals - could not initialize collection" ));
  431. delete p;
  432. return hr;
  433. }
  434. //
  435. // get the IDispatch interface
  436. //
  437. hr = p->_InternalQueryInterface(
  438. IID_IDispatch,
  439. (void **) &pDisp
  440. );
  441. if (S_OK != hr)
  442. {
  443. LOG((TL_ERROR, "get_StaticTerminals - could not get IDispatch interface" ));
  444. delete p;
  445. return hr;
  446. }
  447. //
  448. // put it in the variant
  449. //
  450. VariantInit(pVariant);
  451. pVariant->vt = VT_DISPATCH;
  452. pVariant->pdispVal = pDisp;
  453. LOG((
  454. TL_TRACE,
  455. "get_StaticTerminals - exit - return %lx",
  456. hr
  457. ));
  458. LOG((TL_TRACE, "get_StaticTerminals - exit"));
  459. return hr;
  460. }
  461. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  462. //
  463. // CPhoneMSP::EnumerateStaticTerminals
  464. //
  465. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  466. STDMETHODIMP
  467. CPhoneMSP::EnumerateStaticTerminals(IEnumTerminal ** ppEnumTerminal)
  468. {
  469. HRESULT hr = S_OK;
  470. LOG((TL_TRACE, "EnumerateStaticTerminals - enter"));
  471. if (TAPIIsBadWritePtr(ppEnumTerminal, sizeof( IEnumTerminal * ) ) )
  472. {
  473. LOG((TL_ERROR, "EnumerateStaticTerminals - bad pointer"));
  474. return E_POINTER;
  475. }
  476. //
  477. // create the enumerator
  478. //
  479. CComObject< CTapiEnum< IEnumTerminal, ITTerminal, &IID_IEnumTerminal > > * p;
  480. hr = CComObject< CTapiEnum< IEnumTerminal, ITTerminal, &IID_IEnumTerminal > >
  481. ::CreateInstance( &p );
  482. if (S_OK != hr)
  483. {
  484. LOG((TL_ERROR, "EnumerateStaticTerminals - could not create enum" ));
  485. return hr;
  486. }
  487. Lock();
  488. //
  489. // initialize it with our terminal array
  490. //
  491. p->Initialize( m_TerminalArray );
  492. Unlock();
  493. //
  494. // return it
  495. //
  496. *ppEnumTerminal = p;
  497. LOG((
  498. TL_TRACE,
  499. "EnumerateStaticTerminals - exit - return %lx",
  500. hr
  501. ));
  502. return hr;
  503. }
  504. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  505. //
  506. // CPhoneMSP::get_DynamicTerminalClasses
  507. //
  508. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  509. STDMETHODIMP
  510. CPhoneMSP::get_DynamicTerminalClasses(VARIANT * pVariant)
  511. {
  512. HRESULT hr = S_OK;
  513. CComObject< CTerminalClassCollection > * p;
  514. IDispatch * pDisp = NULL;
  515. TerminalClassPtrList classlist;
  516. LOG((TL_TRACE, "get_DynamicTerminalClasses - enter"));
  517. if (TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) )
  518. {
  519. LOG((TL_ERROR, "get_DynamicTerminalClasses - bad pointer"));
  520. return E_POINTER;
  521. }
  522. classlist.clear();
  523. //
  524. // create the object
  525. //
  526. CComObject< CTerminalClassCollection >::CreateInstance( &p );
  527. //
  528. // init it
  529. //
  530. hr = p->Initialize( classlist );
  531. //
  532. // get the IDispatch interface
  533. //
  534. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  535. if (S_OK != hr)
  536. {
  537. LOG((TL_ERROR, "get_dynamicterminalclasses - could not get the IDispatch interface" ));
  538. delete p;
  539. return hr;
  540. }
  541. //
  542. // put it in the variant
  543. //
  544. VariantInit(pVariant);
  545. pVariant->vt = VT_DISPATCH;
  546. pVariant->pdispVal = pDisp;
  547. LOG((
  548. TL_TRACE,
  549. "get_DynamicTerminalClasses - exit - return %lx",
  550. hr
  551. ));
  552. return hr;
  553. }
  554. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  555. //
  556. // CPhoneMSP::EnumerateDynamicTerminalClasses
  557. //
  558. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  559. STDMETHODIMP
  560. CPhoneMSP::EnumerateDynamicTerminalClasses(
  561. IEnumTerminalClass ** ppTerminalClassEnumerator
  562. )
  563. {
  564. HRESULT hr = S_OK;
  565. TerminalClassPtrList termlist;
  566. LOG((TL_TRACE, "EnumerateDynamicTerminalClasses - enter"));
  567. if (TAPIIsBadWritePtr( ppTerminalClassEnumerator, sizeof(IEnumTerminalClass *) ) )
  568. {
  569. LOG((TL_ERROR, "EnumerateDynamicTerminalClasses - bad pointer"));
  570. return E_POINTER;
  571. }
  572. termlist.clear();
  573. //
  574. // create the enumerator
  575. //
  576. CComObject< CTerminalClassEnum > * p;
  577. CComObject< CTerminalClassEnum >::CreateInstance( &p );
  578. if (NULL == p)
  579. {
  580. LOG((TL_TRACE, "_EnumDynTermClasses - create enum failed - return %lx", hr ));
  581. return hr;
  582. }
  583. //
  584. // init it
  585. //
  586. hr = p->Initialize( termlist );
  587. if (!SUCCEEDED( hr ))
  588. {
  589. LOG((TL_TRACE, "_EnumDynTermClasses - init enum failed - return %lx", hr ));
  590. delete p;
  591. return hr;
  592. }
  593. *ppTerminalClassEnumerator = p;
  594. LOG((
  595. TL_TRACE,
  596. "EnumerateDynamicTerminalClasses - exit - return %lx",
  597. hr
  598. ));
  599. return hr;
  600. }
  601. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  602. //
  603. // CPhoneMSP::CreateTerminal
  604. //
  605. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  606. STDMETHODIMP
  607. CPhoneMSP::CreateTerminal(
  608. BSTR TerminalClass,
  609. long lMediaType,
  610. TERMINAL_DIRECTION TerminalDirection,
  611. ITTerminal ** ppTerminal
  612. )
  613. {
  614. HRESULT hr = TAPI_E_NOTSUPPORTED;
  615. LOG((TL_TRACE, "CreateTerminal - enter"));
  616. LOG((
  617. TL_TRACE,
  618. "CreateTerminal - exit - return %lx",
  619. hr
  620. ));
  621. return hr;
  622. }
  623. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  624. //
  625. // CPhoneMSP::GetDefaultStaticTerminal
  626. //
  627. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  628. STDMETHODIMP
  629. CPhoneMSP::GetDefaultStaticTerminal(
  630. long lMediaType,
  631. TERMINAL_DIRECTION Dir,
  632. ITTerminal ** ppTerminal
  633. )
  634. {
  635. HRESULT hr = S_OK;
  636. int iSize, iCount;
  637. LOG((TL_TRACE, "GetDefaultStaticTerminal - enter"));
  638. if ( TAPIIsBadWritePtr( ppTerminal, sizeof (ITTerminal *) ) )
  639. {
  640. LOG((TL_TRACE, "GetDefaultStaticTerminal - bad pointer"));
  641. return E_POINTER;
  642. }
  643. Lock();
  644. iSize = m_TerminalArray.GetSize();
  645. for ( iCount = 0; iCount < iSize; iCount++ )
  646. {
  647. TERMINAL_DIRECTION td;
  648. long lTermMediaType;
  649. hr = m_TerminalArray[iCount]->get_Direction( &td );
  650. if ( SUCCEEDED(hr) )
  651. {
  652. hr = m_TerminalArray[iCount]->get_MediaType( &lTermMediaType );
  653. if ( SUCCEEDED(hr) )
  654. {
  655. if ( ( td == Dir ) &&
  656. ( lTermMediaType == lMediaType ) )
  657. {
  658. *ppTerminal = m_TerminalArray[iCount];
  659. (*ppTerminal)->AddRef();
  660. Unlock();
  661. LOG((
  662. TL_TRACE,
  663. "GetDefaultStaticTerminal - exit - return S_OK"
  664. ));
  665. return S_OK;
  666. }
  667. }
  668. }
  669. }
  670. Unlock();
  671. hr = TAPI_E_INVALIDTERMINAL;
  672. LOG((
  673. TL_TRACE,
  674. "GetDefaultStaticTerminal - exit - return %lx",
  675. hr
  676. ));
  677. return hr;
  678. }
  679. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  680. //
  681. // CreateStream
  682. //
  683. // dwMediaType - mediatype of new stream
  684. //
  685. // td - direction of new stream
  686. //
  687. // ppStream - returned stream
  688. //
  689. // always fails - phone terminals don't handle this type of
  690. // functionality
  691. //
  692. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  693. STDMETHODIMP
  694. CPhoneMSPCall::CreateStream(
  695. long dwMediaType,
  696. TERMINAL_DIRECTION td,
  697. ITStream ** ppStream
  698. )
  699. {
  700. HRESULT hr = TAPI_E_NOTSUPPORTED;
  701. LOG((TL_TRACE, "CreateStream - enter"));
  702. LOG((TL_TRACE, "CreateStream - exit - return %lx", hr));
  703. return hr;
  704. }
  705. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  706. //
  707. // RemoveStream
  708. //
  709. // pStream - stream to remove
  710. //
  711. // always fail - phone terminals don't handle this type of
  712. // functionality.
  713. //
  714. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  715. STDMETHODIMP
  716. CPhoneMSPCall::RemoveStream(
  717. ITStream * pStream
  718. )
  719. {
  720. HRESULT hr = TAPI_E_NOTSUPPORTED;
  721. LOG((TL_TRACE, "RemoveStream - enter"));
  722. LOG((TL_TRACE, "RemoveStream - exit - return %lx", hr));
  723. return hr;
  724. }
  725. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  726. //
  727. // EnumerateStreams
  728. //
  729. // ppEnumStream - returned enumerator
  730. //
  731. // enumerates the streams available. this should always be
  732. // audio in and audio out
  733. //
  734. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  735. STDMETHODIMP
  736. CPhoneMSPCall::EnumerateStreams(
  737. IEnumStream ** ppEnumStream
  738. )
  739. {
  740. HRESULT hr = S_OK;
  741. LOG((TL_TRACE, "EnumerateStreams - enter"));
  742. if (TAPIIsBadWritePtr(ppEnumStream, sizeof( IEnumStream * ) ) )
  743. {
  744. LOG((TL_ERROR, "EnumerateStreams - bad pointer"));
  745. return E_POINTER;
  746. }
  747. //
  748. // create the enumerator
  749. //
  750. CComObject< CTapiEnum< IEnumStream, ITStream, &IID_IEnumStream > > * p;
  751. hr = CComObject< CTapiEnum< IEnumStream, ITStream, &IID_IEnumStream > >
  752. ::CreateInstance( &p );
  753. if (S_OK != hr)
  754. {
  755. LOG((TL_ERROR, "EnumerateStreams - could not create enum" ));
  756. return hr;
  757. }
  758. Lock();
  759. //
  760. // initialize it with our Stream array
  761. //
  762. p->Initialize( m_StreamArray );
  763. Unlock();
  764. //
  765. // return it
  766. //
  767. *ppEnumStream = p;
  768. LOG((TL_TRACE, "EnumerateStreams - exit - return %lx", hr));
  769. return hr;
  770. }
  771. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  772. //
  773. // get_Streams
  774. //
  775. // pStreams - returned collection
  776. //
  777. // collection of streams - like enumeratestreams
  778. //
  779. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  780. STDMETHODIMP
  781. CPhoneMSPCall::get_Streams(
  782. VARIANT * pStreams
  783. )
  784. {
  785. HRESULT hr = S_OK;
  786. IDispatch * pDisp;
  787. LOG((TL_TRACE, "get_Streams - enter"));
  788. if (TAPIIsBadWritePtr( pStreams, sizeof(VARIANT) ) )
  789. {
  790. LOG((TL_ERROR, "get_Streams - bad pointer"));
  791. return E_POINTER;
  792. }
  793. CComObject< CTapiCollection< ITStream > > * p;
  794. CComObject< CTapiCollection< ITStream > >::CreateInstance( &p );
  795. if (NULL == p)
  796. {
  797. LOG((TL_ERROR, "get_Streams - could not create collection" ));
  798. return E_OUTOFMEMORY;
  799. }
  800. Lock();
  801. // initialize
  802. hr = p->Initialize( m_StreamArray );
  803. Unlock();
  804. if (S_OK != hr)
  805. {
  806. LOG((TL_ERROR, "get_Streams - could not initialize collection" ));
  807. delete p;
  808. return hr;
  809. }
  810. //
  811. // get the IDispatch interface
  812. //
  813. hr = p->_InternalQueryInterface(
  814. IID_IDispatch,
  815. (void **) &pDisp
  816. );
  817. if (S_OK != hr)
  818. {
  819. LOG((TL_ERROR, "get_Streams - could not get IDispatch interface" ));
  820. delete p;
  821. return hr;
  822. }
  823. //
  824. // put it in the variant
  825. //
  826. VariantInit(pStreams);
  827. pStreams->vt = VT_DISPATCH;
  828. pStreams->pdispVal = pDisp;
  829. LOG((TL_TRACE, "get_Streams - exit - return %lx", hr));
  830. return hr;
  831. }
  832. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  833. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  834. STDMETHODIMP
  835. CPhoneMSPCall::Initialize(
  836. CPhoneMSP * pPhoneMSP
  837. )
  838. {
  839. HRESULT hr;
  840. ITStream * pStream;
  841. ITPhoneMSPCallPrivate * pCallPrivate;
  842. hr = QueryInterface(
  843. IID_ITPhoneMSPCallPrivate,
  844. (void**)&pCallPrivate
  845. );
  846. if ( !SUCCEEDED(hr) )
  847. {
  848. LOG((TL_ERROR, "Initialize - out of memory" ));
  849. return E_OUTOFMEMORY;
  850. }
  851. m_t3Phone.hPhone = NULL;
  852. m_t3Phone.pMSPCall = pCallPrivate;
  853. m_pPhoneMSP = pPhoneMSP;
  854. hr = CStream::InternalCreateStream(
  855. TAPIMEDIATYPE_AUDIO,
  856. TD_RENDER,
  857. pCallPrivate,
  858. &pStream
  859. );
  860. if ( !SUCCEEDED(hr) )
  861. {
  862. pCallPrivate->Release();
  863. LOG((TL_ERROR, "Initialize - out of memory" ));
  864. return E_OUTOFMEMORY;
  865. }
  866. AddStream( pStream );
  867. pStream->Release();
  868. hr = CStream::InternalCreateStream(
  869. TAPIMEDIATYPE_AUDIO,
  870. TD_CAPTURE,
  871. pCallPrivate,
  872. &pStream
  873. );
  874. if ( !SUCCEEDED(hr) )
  875. {
  876. pCallPrivate->Release();
  877. LOG((TL_ERROR, "Initialize - out of memory" ));
  878. return E_OUTOFMEMORY;
  879. }
  880. AddStream( pStream );
  881. pStream->Release();
  882. pCallPrivate->Release();
  883. return S_OK;
  884. }
  885. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  886. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  887. void
  888. CPhoneMSPCall::FinalRelease()
  889. {
  890. m_StreamArray.Shutdown();
  891. m_TerminalArray.Shutdown();
  892. }
  893. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  894. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  895. void
  896. CPhoneMSPCall::AddStream( ITStream * pStream )
  897. {
  898. Lock();
  899. m_StreamArray.Add( pStream );
  900. Unlock();
  901. }
  902. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  903. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  904. void
  905. CPhoneMSPCall::AddTerminal( ITTerminalPrivate * pTerminal )
  906. {
  907. Lock();
  908. m_TerminalArray.Add( pTerminal );
  909. pTerminal->SetMSPCall( this );
  910. if ( PHONEMSP_CONNECTED == m_State )
  911. {
  912. }
  913. Unlock();
  914. }
  915. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  916. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  917. void
  918. CPhoneMSPCall::RemoveTerminal( ITTerminalPrivate * pTerminal )
  919. {
  920. BOOL bRemoved;
  921. Lock();
  922. bRemoved = m_TerminalArray.Remove( pTerminal );
  923. if ( bRemoved && (PHONEMSP_DISCONNECTED == m_State) )
  924. {
  925. pTerminal->SetMSPCall( NULL );
  926. }
  927. Unlock();
  928. }
  929. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  930. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  931. STDMETHODIMP
  932. CPhoneMSPCall::OnConnect()
  933. {
  934. HRESULT hr = S_OK;
  935. int iSize, iCount;
  936. DWORD dwHookSwitchDev = 0;
  937. HPHONEAPP hPhoneApp = NULL;
  938. DWORD dwPhoneID = 0;
  939. DWORD dwAPIVersion;
  940. LOG((TL_TRACE, "OnConnect - enter"));
  941. Lock();
  942. m_State = PHONEMSP_CONNECTED;
  943. iSize = m_TerminalArray.GetSize();
  944. if ( 0 == iSize )
  945. {
  946. Unlock();
  947. return S_OK;
  948. }
  949. for ( iCount = 0; iCount < iSize; iCount++ )
  950. {
  951. DWORD dwHoldHookSwitchDev;
  952. m_TerminalArray[iCount]->GetHookSwitchDev( &dwHoldHookSwitchDev );
  953. dwHookSwitchDev |= dwHoldHookSwitchDev;
  954. }
  955. m_TerminalArray[0]->GetHPhoneApp( &hPhoneApp );
  956. m_TerminalArray[0]->GetPhoneID( &dwPhoneID );
  957. m_TerminalArray[0]->GetAPIVersion( &dwAPIVersion );
  958. if (m_t3Phone.hPhone == NULL)
  959. {
  960. hr = PhoneOpen(
  961. hPhoneApp,
  962. dwPhoneID,
  963. &m_t3Phone,
  964. dwAPIVersion,
  965. PHONEPRIVILEGE_OWNER
  966. );
  967. if ( !SUCCEEDED(hr) )
  968. {
  969. }
  970. }
  971. ASYNCEVENTMSG Msg;
  972. Msg.Msg = PRIVATE_PHONESETHOOKSWITCH;
  973. Msg.TotalSize = sizeof (ASYNCEVENTMSG);
  974. Msg.hDevice = (ULONG_PTR) this;
  975. Msg.Param1 = PHONEHOOKSWITCHMODE_MICSPEAKER;
  976. Msg.Param2 = dwHookSwitchDev;
  977. AddRef();
  978. QueueCallbackEvent( &Msg );
  979. Unlock();
  980. LOG((TL_TRACE,hr, "OnConnect - exit"));
  981. return hr;
  982. }
  983. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  984. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  985. STDMETHODIMP
  986. CPhoneMSPCall::OnDisconnect()
  987. {
  988. HRESULT hr = S_OK;
  989. LOG((TL_TRACE, "OnDisconnect - enter"));
  990. Lock();
  991. if (m_t3Phone.hPhone != NULL)
  992. {
  993. hr = PhoneClose(m_t3Phone.hPhone);
  994. m_t3Phone.hPhone = NULL;
  995. }
  996. m_State = PHONEMSP_DISCONNECTED;
  997. Unlock();
  998. LOG((TL_TRACE,hr, "OnDisconnect - exit"));
  999. return hr;
  1000. }
  1001. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1002. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1003. STDMETHODIMP
  1004. CPhoneMSPCall::SelectTerminal( ITTerminalPrivate * pTerminal )
  1005. {
  1006. ITTerminal * pITTerminal;
  1007. HRESULT hr;
  1008. hr = pTerminal->QueryInterface(
  1009. IID_ITTerminal,
  1010. (void**) &pITTerminal
  1011. );
  1012. if ( SUCCEEDED(hr) )
  1013. {
  1014. hr = m_pPhoneMSP->VerifyTerminal( pITTerminal );
  1015. pITTerminal->Release();
  1016. if ( SUCCEEDED(hr) )
  1017. {
  1018. AddTerminal( pTerminal );
  1019. }
  1020. }
  1021. return hr;
  1022. }
  1023. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1024. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1025. STDMETHODIMP
  1026. CPhoneMSPCall::UnselectTerminal( ITTerminalPrivate * pTerminal )
  1027. {
  1028. RemoveTerminal( pTerminal );
  1029. return S_OK;
  1030. }
  1031. STDMETHODIMP
  1032. CPhoneMSPCall::GetGain(long *pVal, DWORD dwHookSwitch)
  1033. {
  1034. HRESULT hr;
  1035. hr = PhoneGetGain(
  1036. m_t3Phone.hPhone,
  1037. dwHookSwitch,
  1038. (DWORD *)pVal
  1039. );
  1040. if ( ((long)hr) > 0 )
  1041. {
  1042. hr = WaitForPhoneReply( hr );
  1043. }
  1044. return hr;
  1045. }
  1046. STDMETHODIMP
  1047. CPhoneMSPCall::PutGain(long newVal, DWORD dwHookSwitch)
  1048. {
  1049. HRESULT hr;
  1050. hr = PhoneSetGain(
  1051. m_t3Phone.hPhone,
  1052. dwHookSwitch,
  1053. newVal
  1054. );
  1055. if ( ((long)hr) > 0 )
  1056. {
  1057. hr = WaitForPhoneReply( hr );
  1058. }
  1059. return hr;
  1060. }
  1061. STDMETHODIMP
  1062. CPhoneMSPCall::GetVolume(long *pVal, DWORD dwHookSwitch)
  1063. {
  1064. HRESULT hr;
  1065. hr = PhoneGetVolume(
  1066. m_t3Phone.hPhone,
  1067. dwHookSwitch,
  1068. (DWORD *)pVal
  1069. );
  1070. if ( ((long)hr) > 0 )
  1071. {
  1072. hr = WaitForPhoneReply( hr );
  1073. }
  1074. return hr;
  1075. }
  1076. STDMETHODIMP
  1077. CPhoneMSPCall::PutVolume(long newVal, DWORD dwHookSwitch)
  1078. {
  1079. HRESULT hr;
  1080. hr = PhoneSetVolume(
  1081. m_t3Phone.hPhone,
  1082. dwHookSwitch,
  1083. newVal
  1084. );
  1085. if ( ((long)hr) > 0 )
  1086. {
  1087. hr = WaitForPhoneReply( hr );
  1088. }
  1089. return hr;
  1090. }
  1091. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1092. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1093. void
  1094. CPhoneMSPCall::HandlePrivateHookSwitch( PASYNCEVENTMSG pParams )
  1095. {
  1096. CPhoneMSPCall * pMSPCall;
  1097. HRESULT hr;
  1098. pMSPCall = (CPhoneMSPCall *)(pParams->hDevice);
  1099. hr = PhoneSetHookSwitch(
  1100. pMSPCall->m_t3Phone.hPhone,
  1101. pParams->Param2,
  1102. pParams->Param1
  1103. );
  1104. if ( SUCCEEDED(hr) )
  1105. {
  1106. hr = WaitForPhoneReply(hr);
  1107. }
  1108. pMSPCall->Release();
  1109. }