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.

13669 lines
350 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. address.cpp
  5. Abstract:
  6. Implementation of the Address object for TAPI 3.0.
  7. Author:
  8. mquinton - 4/17/97
  9. Notes:
  10. optional-notes
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "uuids.h"
  15. #include "TermEvnt.h"
  16. #include "tapievt.h"
  17. const CLSID CLSID_WAVEMSP = {0x4DDB6D36,0x3BC1,0x11d2,{0x86,0xF2,0x00,0x60,0x08,0xB0,0xE5,0xD2}};
  18. extern HRESULT mapTAPIErrorCode(long lErrorCode);
  19. extern ULONG_PTR GenerateHandleAndAddToHashTable( ULONG_PTR Element);
  20. extern void RemoveHandleFromHashTable(ULONG_PTR dwHandle);
  21. extern CHashTable * gpHandleHashTable;
  22. extern CRetryQueue * gpRetryQueue;
  23. extern HANDLE ghAsyncRetryQueueEvent;
  24. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  25. // WAITORTIMERCALLBACK
  26. // CAddress::MSPEventCallback(
  27. // PVOID pContext,
  28. // BOOLEAN b
  29. // )
  30. //
  31. // this is the callback that gets called when an msp
  32. // sets it's message event
  33. //
  34. // queues a message to be handled in the callback thread
  35. //
  36. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  37. VOID
  38. NTAPI
  39. MSPEventCallback(
  40. VOID * pContext,
  41. BOOLEAN bFlag
  42. )
  43. {
  44. CAddress * pAddress;
  45. HRESULT hr;
  46. gpHandleHashTable->Lock();
  47. hr = gpHandleHashTable->Find( (ULONG_PTR)pContext, (ULONG_PTR *)&pAddress );
  48. if ( SUCCEEDED(hr) )
  49. {
  50. LOG((TL_INFO, "MSPEventCallback - Matched handle %p to Address object %p", pContext, pAddress ));
  51. ASYNCEVENTMSG msg;
  52. DWORD dwAddressHandle;
  53. pAddress->AddRef();
  54. gpHandleHashTable->Unlock();
  55. dwAddressHandle = CreateHandleTableEntry ((ULONG_PTR)pAddress);
  56. if (0 != dwAddressHandle)
  57. {
  58. ZeroMemory( &msg, sizeof(msg) );
  59. msg.TotalSize = sizeof(msg);
  60. msg.Msg = PRIVATE_MSPEVENT;
  61. msg.Param1 = dwAddressHandle;
  62. //
  63. // try to queue the event
  64. //
  65. BOOL bQueueEventSuccess = gpRetryQueue->QueueEvent(&msg);
  66. if (bQueueEventSuccess)
  67. {
  68. SetEvent(ghAsyncRetryQueueEvent);
  69. }
  70. else
  71. {
  72. //
  73. // RetryQueue is either no longer accepting entries or
  74. // failed to allocate resources it needed.
  75. //
  76. // in any case, the event will not be processed. cleanup.
  77. //
  78. DeleteHandleTableEntry (dwAddressHandle);
  79. pAddress->Release();
  80. pAddress = NULL;
  81. LOG((TL_ERROR, "MSPEventCallback - Couldn't enqueue event"));
  82. }
  83. }
  84. }
  85. else
  86. {
  87. LOG((TL_ERROR, "MSPEventCallback - Couldn't match handle %p to Address object ", pContext));
  88. gpHandleHashTable->Unlock();
  89. }
  90. }
  91. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  92. //
  93. // void HandlePrivateMSPEvent( PASYNCEVENTMSG pParams )
  94. //
  95. // actually handles the msp event. this is called in the
  96. // asynceventsthread
  97. //
  98. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  99. void HandlePrivateMSPEvent( PASYNCEVENTMSG pParams )
  100. {
  101. CAddress * pAddress;
  102. pAddress = (CAddress *) GetHandleTableEntry(pParams->Param1);
  103. DeleteHandleTableEntry (pParams->Param1);
  104. if (NULL != pAddress)
  105. {
  106. pAddress->MSPEvent();
  107. //
  108. // address is addref'd when event
  109. // is packaged.
  110. //
  111. pAddress->Release();
  112. }
  113. }
  114. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  115. //
  116. // Class : CEventMasks
  117. // Method : SetSubEventFlag
  118. //
  119. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  120. HRESULT CEventMasks::SetSubEventFlag(
  121. DWORD dwEvent, // The event
  122. DWORD dwFlag, // The flag that should be set
  123. BOOL bEnable
  124. )
  125. {
  126. //
  127. // Enter critical section
  128. //
  129. //m_cs.Lock();
  130. //
  131. // Prepare the subevent flag
  132. //
  133. DWORD dwSubEventFlag = 0;
  134. dwSubEventFlag = (dwFlag == EM_ALLSUBEVENTS ) ?
  135. EM_ALLSUBEVENTS :
  136. GET_SUBEVENT_FLAG( dwFlag );
  137. //
  138. // Set the mask for the events
  139. //
  140. switch( dwEvent )
  141. {
  142. case EM_ALLEVENTS:
  143. case TE_TAPIOBJECT:
  144. if( bEnable )
  145. {
  146. // Set the bit
  147. m_dwTapiObjectMask = m_dwTapiObjectMask | dwSubEventFlag;
  148. }
  149. else
  150. {
  151. // Reset the bit
  152. m_dwTapiObjectMask = m_dwTapiObjectMask & ( ~dwSubEventFlag );
  153. }
  154. if( dwEvent == TE_TAPIOBJECT)
  155. {
  156. break;
  157. }
  158. case TE_ADDRESS:
  159. if( bEnable )
  160. {
  161. // Set the bit
  162. m_dwAddressMask = m_dwAddressMask | dwSubEventFlag;
  163. }
  164. else
  165. {
  166. // Reset the bit
  167. m_dwAddressMask = m_dwAddressMask & ( ~dwSubEventFlag );
  168. }
  169. if( dwEvent == TE_ADDRESS)
  170. {
  171. break;
  172. }
  173. case TE_CALLNOTIFICATION:
  174. if( bEnable )
  175. {
  176. // Set the bit
  177. m_dwCallNotificationMask = m_dwCallNotificationMask | dwSubEventFlag;
  178. }
  179. else
  180. {
  181. // Reset the bit
  182. m_dwCallNotificationMask = m_dwCallNotificationMask & ( ~dwSubEventFlag );
  183. }
  184. if( dwEvent == TE_CALLNOTIFICATION)
  185. {
  186. break;
  187. }
  188. case TE_CALLSTATE:
  189. if( bEnable )
  190. {
  191. // Set the bit
  192. m_dwCallStateMask = m_dwCallStateMask | dwSubEventFlag;
  193. }
  194. else
  195. {
  196. // Reset the bit
  197. m_dwCallStateMask = m_dwCallStateMask & ( ~dwSubEventFlag );
  198. }
  199. if( dwEvent == TE_CALLSTATE)
  200. {
  201. break;
  202. }
  203. case TE_CALLMEDIA:
  204. if( bEnable )
  205. {
  206. // Set the bit
  207. m_dwCallMediaMask = m_dwCallMediaMask | dwSubEventFlag;
  208. }
  209. else
  210. {
  211. // Reset the bit
  212. m_dwCallMediaMask = m_dwCallMediaMask & ( ~dwSubEventFlag );
  213. }
  214. if( dwEvent == TE_CALLMEDIA)
  215. {
  216. break;
  217. }
  218. case TE_CALLHUB:
  219. if( bEnable )
  220. {
  221. // Set the bit
  222. m_dwCallHubMask = m_dwCallHubMask | dwSubEventFlag;
  223. }
  224. else
  225. {
  226. // Reset the bit
  227. m_dwCallHubMask = m_dwCallHubMask & ( ~dwSubEventFlag );
  228. }
  229. if( dwEvent == TE_CALLHUB)
  230. {
  231. break;
  232. }
  233. case TE_CALLINFOCHANGE:
  234. if( bEnable )
  235. {
  236. // Set the bit
  237. m_dwCallInfoChangeMask = m_dwCallInfoChangeMask | dwSubEventFlag;
  238. }
  239. else
  240. {
  241. // Reset the bit
  242. m_dwCallInfoChangeMask = m_dwCallInfoChangeMask & ( ~dwSubEventFlag );
  243. }
  244. if( dwEvent == TE_CALLINFOCHANGE)
  245. {
  246. break;
  247. }
  248. case TE_QOSEVENT:
  249. if( bEnable )
  250. {
  251. // Set the bit
  252. m_dwQOSEventMask = m_dwQOSEventMask | dwSubEventFlag;
  253. }
  254. else
  255. {
  256. // Reset the bit
  257. m_dwQOSEventMask = m_dwQOSEventMask & ( ~dwSubEventFlag );
  258. }
  259. if( dwEvent == TE_QOSEVENT)
  260. {
  261. break;
  262. }
  263. case TE_FILETERMINAL:
  264. if( bEnable )
  265. {
  266. // Set the bit
  267. m_dwFileTerminalMask = m_dwFileTerminalMask | dwSubEventFlag;
  268. }
  269. else
  270. {
  271. // Reset the bit
  272. m_dwFileTerminalMask = m_dwFileTerminalMask & ( ~dwSubEventFlag );
  273. }
  274. if( dwEvent == TE_FILETERMINAL)
  275. {
  276. break;
  277. }
  278. case TE_PRIVATE:
  279. if( bEnable )
  280. {
  281. // Set the entire mask
  282. m_dwPrivateMask = EM_ALLSUBEVENTS;
  283. }
  284. else
  285. {
  286. // Reset the entire mask
  287. m_dwPrivateMask = 0;
  288. }
  289. if( dwEvent == TE_PRIVATE)
  290. {
  291. break;
  292. }
  293. case TE_ADDRESSDEVSPECIFIC:
  294. if( bEnable )
  295. {
  296. // Set the bit
  297. m_dwAddressDevSpecificMask = m_dwAddressDevSpecificMask | dwSubEventFlag;
  298. }
  299. else
  300. {
  301. // Reset the bit
  302. m_dwAddressDevSpecificMask = m_dwAddressDevSpecificMask & ( ~dwSubEventFlag );
  303. }
  304. if( dwEvent == TE_ADDRESSDEVSPECIFIC)
  305. {
  306. break;
  307. }
  308. case TE_PHONEDEVSPECIFIC:
  309. if( bEnable )
  310. {
  311. // Set the bit
  312. m_dwPhoneDevSpecificMask = m_dwPhoneDevSpecificMask | dwSubEventFlag;
  313. }
  314. else
  315. {
  316. // Reset the bit
  317. m_dwPhoneDevSpecificMask = m_dwPhoneDevSpecificMask & ( ~dwSubEventFlag );
  318. }
  319. if( dwEvent == TE_PHONEDEVSPECIFIC)
  320. {
  321. break;
  322. }
  323. }
  324. //
  325. // Leave critical section
  326. //
  327. //m_cs.Unlock();
  328. return S_OK;
  329. }
  330. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  331. //
  332. // Class : CEventMasks
  333. // Method : GetSubEventFlag
  334. //
  335. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  336. HRESULT CEventMasks::GetSubEventFlag(
  337. DWORD dwEvent, // The event
  338. DWORD dwFlag, // The flag that should be setted
  339. BOOL* pEnable
  340. )
  341. {
  342. //
  343. // Enter critical section
  344. //
  345. //m_cs.Lock();
  346. //
  347. // Prepare the subevent flag
  348. //
  349. DWORD dwSubEventFlag = 0;
  350. dwSubEventFlag = GET_SUBEVENT_FLAG( dwFlag );
  351. //
  352. // Reset thre flag
  353. //
  354. *pEnable = FALSE;
  355. //
  356. // Get the flag for the events
  357. //
  358. switch( dwEvent )
  359. {
  360. case TE_TAPIOBJECT:
  361. *pEnable = ((m_dwTapiObjectMask & dwSubEventFlag) != 0);
  362. break;
  363. case TE_ADDRESS:
  364. *pEnable = ((m_dwAddressMask & dwSubEventFlag) != 0);
  365. break;
  366. case TE_CALLNOTIFICATION:
  367. *pEnable = ((m_dwCallNotificationMask & dwSubEventFlag) != 0);
  368. break;
  369. case TE_CALLSTATE:
  370. *pEnable = ((m_dwCallStateMask & dwSubEventFlag) != 0);
  371. break;
  372. case TE_CALLMEDIA:
  373. *pEnable = ((m_dwCallMediaMask & dwSubEventFlag) != 0);
  374. break;
  375. case TE_CALLHUB:
  376. *pEnable = ((m_dwCallHubMask & dwSubEventFlag) != 0);
  377. break;
  378. case TE_CALLINFOCHANGE:
  379. *pEnable = ((m_dwCallInfoChangeMask & dwSubEventFlag) != 0);
  380. break;
  381. case TE_QOSEVENT:
  382. *pEnable = ((m_dwQOSEventMask & dwSubEventFlag) != 0);
  383. break;
  384. case TE_FILETERMINAL:
  385. *pEnable = ((m_dwFileTerminalMask & dwSubEventFlag) != 0);
  386. break;
  387. case TE_PRIVATE:
  388. // We don't have subevents for private events
  389. *pEnable = ( m_dwPrivateMask != 0);
  390. break;
  391. case TE_ADDRESSDEVSPECIFIC:
  392. // We don't have subevents for TE_ADDRESSDEVSPECIFIC events
  393. *pEnable = ( m_dwAddressDevSpecificMask != 0);
  394. break;
  395. case TE_PHONEDEVSPECIFIC:
  396. // We don't have subevents for TE_PHONEDEVSPECIFIC events
  397. *pEnable = ( m_dwPhoneDevSpecificMask != 0);
  398. break;
  399. }
  400. //
  401. // Leave critical section
  402. //
  403. //m_cs.Unlock();
  404. return S_OK;
  405. }
  406. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  407. //
  408. // Class : CEventMasks
  409. // Method : GetSubEventMask
  410. //
  411. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  412. DWORD CEventMasks::GetSubEventMask(
  413. TAPI_EVENT TapiEvent
  414. )
  415. {
  416. //
  417. // Enter critical section
  418. //
  419. //m_cs.Lock();
  420. DWORD dwSubEventMask = EM_NOSUBEVENTS;
  421. switch( TapiEvent )
  422. {
  423. case TE_TAPIOBJECT:
  424. dwSubEventMask = m_dwTapiObjectMask;
  425. break;
  426. case TE_ADDRESS:
  427. dwSubEventMask = m_dwAddressMask;
  428. break;
  429. case TE_CALLNOTIFICATION:
  430. dwSubEventMask = m_dwCallNotificationMask;
  431. break;
  432. case TE_CALLSTATE:
  433. dwSubEventMask = m_dwCallStateMask;
  434. break;
  435. case TE_CALLMEDIA:
  436. dwSubEventMask = m_dwCallMediaMask;
  437. break;
  438. case TE_CALLHUB:
  439. dwSubEventMask = m_dwCallHubMask;
  440. break;
  441. case TE_CALLINFOCHANGE:
  442. dwSubEventMask = m_dwCallInfoChangeMask;
  443. break;
  444. case TE_QOSEVENT:
  445. dwSubEventMask = m_dwQOSEventMask;
  446. break;
  447. case TE_FILETERMINAL:
  448. dwSubEventMask = m_dwFileTerminalMask;
  449. break;
  450. case TE_PRIVATE:
  451. dwSubEventMask = m_dwPrivateMask;
  452. break;
  453. case TE_ADDRESSDEVSPECIFIC:
  454. dwSubEventMask = m_dwAddressDevSpecificMask;
  455. break;
  456. case TE_PHONEDEVSPECIFIC:
  457. dwSubEventMask = m_dwPhoneDevSpecificMask;
  458. break;
  459. default:
  460. dwSubEventMask = EM_NOSUBEVENTS;
  461. break;
  462. }
  463. //
  464. // Leave critical section
  465. //
  466. //m_cs.Unlock();
  467. return dwSubEventMask;
  468. }
  469. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  470. //
  471. // Class : CEventMasks
  472. // Method : IsSubEventValid
  473. //
  474. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  475. BOOL CEventMasks::IsSubEventValid(
  476. TAPI_EVENT TapiEvent,
  477. DWORD dwSubEvent,
  478. BOOL bAcceptAllSubEvents,
  479. BOOL bCallLevel
  480. )
  481. {
  482. BOOL bValid = TRUE;
  483. switch( TapiEvent )
  484. {
  485. case TE_TAPIOBJECT:
  486. //
  487. // Just at the address level
  488. //
  489. if( bCallLevel)
  490. {
  491. bValid = FALSE;
  492. break;
  493. }
  494. //
  495. // ALLSUBEVENTS
  496. //
  497. if( bAcceptAllSubEvents )
  498. {
  499. //
  500. // We could accept 'ALLSUBEVENTS' flag
  501. // when we try to set for all subevents
  502. //
  503. if(dwSubEvent == EM_ALLSUBEVENTS)
  504. {
  505. break;
  506. }
  507. }
  508. //
  509. // In CTapiObjectEvent::get_Address we accept just
  510. // these three subevents
  511. //
  512. if( (dwSubEvent != TE_ADDRESSCREATE) &&
  513. (dwSubEvent != TE_ADDRESSREMOVE) &&
  514. (dwSubEvent != TE_ADDRESSCLOSE) )
  515. {
  516. bValid = FALSE;
  517. }
  518. break;
  519. case TE_ADDRESS:
  520. //
  521. // Just at the address level
  522. //
  523. if( bCallLevel)
  524. {
  525. bValid = FALSE;
  526. break;
  527. }
  528. //
  529. // ALLSUBEVENTS
  530. //
  531. if( bAcceptAllSubEvents )
  532. {
  533. //
  534. // We could accept 'ALLSUBEVENTS' flag
  535. // when we try to set for all subevents
  536. //
  537. if(dwSubEvent == EM_ALLSUBEVENTS)
  538. {
  539. break;
  540. }
  541. }
  542. if( AE_LASTITEM < dwSubEvent )
  543. {
  544. bValid = FALSE;
  545. }
  546. break;
  547. case TE_CALLNOTIFICATION:
  548. //
  549. // Just at the address level
  550. //
  551. if( bCallLevel )
  552. {
  553. bValid = FALSE;
  554. break;
  555. }
  556. //
  557. // Accept at address and call level
  558. // ALLSUBEVENTS
  559. //
  560. if( bAcceptAllSubEvents )
  561. {
  562. //
  563. // We could accept 'ALLSUBEVENTS' flag
  564. // when we try to set for all subevents
  565. //
  566. if(dwSubEvent == EM_ALLSUBEVENTS)
  567. {
  568. break;
  569. }
  570. }
  571. if( CNE_LASTITEM < dwSubEvent )
  572. {
  573. bValid = FALSE;
  574. }
  575. break;
  576. case TE_CALLSTATE:
  577. //
  578. // Accept at address and call level
  579. // ALLSUBEVENTS
  580. //
  581. if( bAcceptAllSubEvents )
  582. {
  583. //
  584. // We could accept 'ALLSUBEVENTS' flag
  585. // when we try to set for all subevents
  586. //
  587. if(dwSubEvent == EM_ALLSUBEVENTS)
  588. {
  589. break;
  590. }
  591. }
  592. if( CS_LASTITEM < dwSubEvent )
  593. {
  594. bValid = FALSE;
  595. }
  596. break;
  597. case TE_CALLMEDIA:
  598. //
  599. // Accept at address and call level
  600. // ALLSUBEVENTS
  601. //
  602. if( bAcceptAllSubEvents )
  603. {
  604. //
  605. // We could accept 'ALLSUBEVENTS' flag
  606. // when we try to set for all subevents
  607. //
  608. if(dwSubEvent == EM_ALLSUBEVENTS)
  609. {
  610. break;
  611. }
  612. }
  613. if( CME_LASTITEM < dwSubEvent )
  614. {
  615. bValid = FALSE;
  616. }
  617. break;
  618. case TE_CALLHUB:
  619. //
  620. // Accept at address and call level
  621. // ALLSUBEVENTS
  622. //
  623. if( bAcceptAllSubEvents )
  624. {
  625. //
  626. // We could accept 'ALLSUBEVENTS' flag
  627. // when we try to set for all subevents
  628. //
  629. if(dwSubEvent == EM_ALLSUBEVENTS)
  630. {
  631. break;
  632. }
  633. }
  634. if( CHE_LASTITEM < dwSubEvent )
  635. {
  636. bValid = FALSE;
  637. }
  638. break;
  639. case TE_CALLINFOCHANGE:
  640. //
  641. // Accept at address and call level
  642. // ALLSUBEVENTS
  643. //
  644. if( bAcceptAllSubEvents )
  645. {
  646. //
  647. // We could accept 'ALLSUBEVENTS' flag
  648. // when we try to set for all subevents
  649. //
  650. if(dwSubEvent == EM_ALLSUBEVENTS)
  651. {
  652. break;
  653. }
  654. }
  655. if( CIC_LASTITEM < dwSubEvent )
  656. {
  657. bValid = FALSE;
  658. }
  659. break;
  660. case TE_QOSEVENT:
  661. //
  662. // Accept at address and call level
  663. // ALLSUBEVENTS
  664. //
  665. if( bAcceptAllSubEvents )
  666. {
  667. //
  668. // We could accept 'ALLSUBEVENTS' flag
  669. // when we try to set for all subevents
  670. //
  671. if(dwSubEvent == EM_ALLSUBEVENTS)
  672. {
  673. break;
  674. }
  675. }
  676. if( QE_LASTITEM < dwSubEvent )
  677. {
  678. bValid = FALSE;
  679. }
  680. break;
  681. case TE_FILETERMINAL:
  682. //
  683. // Accept at address and call level
  684. // ALLSUBEVENTS
  685. //
  686. if( bAcceptAllSubEvents )
  687. {
  688. //
  689. // We could accept 'ALLSUBEVENTS' flag
  690. // when we try to set for all subevents
  691. //
  692. if(dwSubEvent == EM_ALLSUBEVENTS)
  693. {
  694. break;
  695. }
  696. }
  697. if( TMS_LASTITEM < dwSubEvent )
  698. {
  699. bValid = FALSE;
  700. }
  701. break;
  702. case TE_PRIVATE:
  703. case TE_ADDRESSDEVSPECIFIC:
  704. case TE_PHONEDEVSPECIFIC:
  705. //
  706. // Accept at address and call level
  707. // ALLSUBEVENTS
  708. //
  709. if( bAcceptAllSubEvents )
  710. {
  711. //
  712. // We could accept 'ALLSUBEVENTS' flag
  713. // when we try to set for all subevents
  714. //
  715. if(dwSubEvent == EM_ALLSUBEVENTS)
  716. {
  717. break;
  718. }
  719. }
  720. else
  721. {
  722. // we accept just all subevents because
  723. // we don't have subevents
  724. bValid = TRUE;
  725. break;
  726. }
  727. break;
  728. default:
  729. //
  730. // Invalid event type
  731. //
  732. bValid = FALSE;
  733. break;
  734. }
  735. LOG((TL_TRACE, "IsSubEventValid - exit %d", bValid));
  736. return bValid;
  737. }
  738. HRESULT CEventMasks::CopyEventMasks(
  739. CEventMasks* pEventMasks
  740. )
  741. {
  742. //
  743. // Enter critical section
  744. //
  745. //m_cs.Lock();
  746. pEventMasks->m_dwTapiObjectMask = m_dwTapiObjectMask;
  747. pEventMasks->m_dwAddressMask = m_dwAddressMask;
  748. pEventMasks->m_dwCallNotificationMask = m_dwCallNotificationMask;
  749. pEventMasks->m_dwCallStateMask = m_dwCallStateMask;
  750. pEventMasks->m_dwCallMediaMask = m_dwCallMediaMask;
  751. pEventMasks->m_dwCallHubMask = m_dwCallHubMask;
  752. pEventMasks->m_dwCallInfoChangeMask = m_dwCallInfoChangeMask;
  753. pEventMasks->m_dwQOSEventMask = m_dwQOSEventMask;
  754. pEventMasks->m_dwFileTerminalMask = m_dwFileTerminalMask;
  755. pEventMasks->m_dwPrivateMask = m_dwPrivateMask;
  756. pEventMasks->m_dwAddressDevSpecificMask = m_dwAddressDevSpecificMask;
  757. pEventMasks->m_dwPhoneDevSpecificMask = m_dwPhoneDevSpecificMask;
  758. //
  759. // Leave critical section
  760. //
  761. //m_cs.Unlock();
  762. return S_OK;
  763. }
  764. ULONG64 CEventMasks::GetTapiSrvEventMask(
  765. IN BOOL bCallLevel
  766. )
  767. {
  768. //
  769. // Convert flags to server side 64 bit masks
  770. //
  771. ULONG64 ulEventMask = EM_LINE_CALLSTATE | // TE_CALLSTATE
  772. EM_LINE_APPNEWCALL | // TE_CALLNOTIFICATION
  773. EM_PHONE_CLOSE | // TE_PHONEEVENT
  774. EM_PHONE_STATE | // TE_PHONEEVENT
  775. EM_PHONE_BUTTONMODE | // TE_PHONEEVENT
  776. EM_PHONE_BUTTONSTATE | // TE_PHONEVENT
  777. EM_LINE_APPNEWCALLHUB | // TE_CALLHUB
  778. EM_LINE_CALLHUBCLOSE | // TE_CALLHUB
  779. EM_LINE_CALLINFO; // TE_CALLINFOCHAnGE
  780. BOOL bEnable = FALSE;
  781. if( !bCallLevel)
  782. {
  783. //
  784. // These flags will be not read if we
  785. // ask for call level
  786. //
  787. // TE_TAPIOBJECT - TE_ADDRESSCREATE
  788. // At address level
  789. GetSubEventFlag(TE_TAPIOBJECT, TE_ADDRESSCREATE, &bEnable);
  790. if( bEnable )
  791. {
  792. ulEventMask |= EM_LINE_CREATE;
  793. }
  794. // TE_TAPIOBJECT - TE_ADDRESSREMOVE
  795. // At address level
  796. GetSubEventFlag(TE_TAPIOBJECT, TE_ADDRESSREMOVE, &bEnable);
  797. if( bEnable )
  798. {
  799. ulEventMask |= EM_LINE_REMOVE;
  800. }
  801. // TE_TAPIOBJECT - TE_ADDRESSCLOSE
  802. // At address level
  803. GetSubEventFlag(TE_TAPIOBJECT, TE_ADDRESSCLOSE, &bEnable);
  804. if( bEnable )
  805. {
  806. ulEventMask |= EM_LINE_CLOSE;
  807. }
  808. // AE_NEWTERMINAL : ignore private MSP events
  809. // AE_REMOVETERMINAL : ignore private MSP events
  810. //
  811. // We read also the flags for call level,
  812. // so go ahead.
  813. }
  814. // TE_CALLNOTIFICATION - CNE_OWNER
  815. // At call level
  816. // We pass EM_LINE_APPNEWCALL for TE_CALLNOTIFICATION everytime because
  817. // we need this events for internal TAPI3 status
  818. // See ulEventMask declaration
  819. // TE_CALLSTATE - All the subevents
  820. // At call level
  821. // We always pass EM_LINE_CALLSTATE for TE_CALLSTATE because
  822. // we need this event for internal TAPI3 status
  823. // See ulEventMask declaration
  824. // TE_CALLHUB - CHE_CALLHUBNEW
  825. // At call level
  826. // We always pass EM_LINE_APPNEWCALLHUB, EM_LINE_CALLHUBCLOSE
  827. // for TE_CALLHUB because
  828. // we need this event for internal TAPI3 status
  829. // See ulEventMask declaration
  830. // TE_CALLINFOCHANGE - All the subevents
  831. // At call level
  832. // We always pass EM_LINE_CALLINFO for TE_CALLINFOChANGE because
  833. // we need this event for internal TAPI3 status
  834. // See ulEventMask declaration
  835. // TE_QOSEVENT - All the subevents
  836. // At call level
  837. if ( m_dwQOSEventMask )
  838. {
  839. ulEventMask |= EM_LINE_QOSINFO;
  840. }
  841. if ( m_dwAddressDevSpecificMask )
  842. {
  843. ulEventMask |= EM_LINE_DEVSPECIFIC | EM_LINE_DEVSPECIFICEX;
  844. }
  845. if ( m_dwPhoneDevSpecificMask )
  846. {
  847. ulEventMask |= EM_PHONE_DEVSPECIFIC;
  848. }
  849. // TE_FILTETERMIAL it is an MSP stuff
  850. // TE_PRIVATE it is an SMP stuff
  851. return ulEventMask;
  852. }
  853. DWORD CEventMasks::GetTapiSrvLineStateMask()
  854. {
  855. //
  856. // These flags shuld be read just
  857. // at address level
  858. //
  859. DWORD dwLineDevStateSubMasks = 0;
  860. BOOL bEnable = FALSE;
  861. // TE_ADDRESS - AE_STATE
  862. // At address level
  863. GetSubEventFlag(TE_ADDRESS, AE_STATE, &bEnable);
  864. if( bEnable )
  865. {
  866. dwLineDevStateSubMasks |= LINEDEVSTATE_CONNECTED |
  867. LINEDEVSTATE_INSERVICE |
  868. LINEDEVSTATE_OUTOFSERVICE |
  869. LINEDEVSTATE_MAINTENANCE |
  870. LINEDEVSTATE_REMOVED |
  871. LINEDEVSTATE_DISCONNECTED |
  872. LINEDEVSTATE_LOCK |
  873. LINEDEVSTATE_MSGWAITON |
  874. LINEDEVSTATE_MSGWAITOFF ;
  875. }
  876. // TE_ADDRESS - AE_CAPSCHANGE
  877. // At address level
  878. GetSubEventFlag(TE_ADDRESS, AE_CAPSCHANGE, &bEnable);
  879. if( bEnable )
  880. {
  881. dwLineDevStateSubMasks |= LINEDEVSTATE_CAPSCHANGE;
  882. }
  883. // TE_ADDRESS - AE_RINGING
  884. // At address level
  885. GetSubEventFlag(TE_ADDRESS, AE_RINGING, &bEnable);
  886. if( bEnable )
  887. {
  888. dwLineDevStateSubMasks |= LINEDEVSTATE_RINGING;
  889. }
  890. // TE_ADDRESS - AE_CONFIGCHANGE
  891. // At address level
  892. GetSubEventFlag(TE_ADDRESS, AE_CONFIGCHANGE, &bEnable);
  893. if( bEnable )
  894. {
  895. dwLineDevStateSubMasks |= LINEDEVSTATE_CONFIGCHANGE;
  896. }
  897. return dwLineDevStateSubMasks;
  898. }
  899. DWORD CEventMasks::GetTapiSrvAddrStateMask()
  900. {
  901. //
  902. // These flags should be read just
  903. // at address level
  904. //
  905. DWORD dwAddrStateSubMasks = 0;
  906. BOOL bEnable = FALSE;
  907. // TE_ADDRESS - AE_CAPSCHANGE
  908. // Address level
  909. GetSubEventFlag(TE_ADDRESS, AE_CAPSCHANGE, &bEnable);
  910. if( bEnable )
  911. {
  912. dwAddrStateSubMasks |= LINEADDRESSSTATE_CAPSCHANGE |
  913. LINEDEVSTATE_CAPSCHANGE;
  914. }
  915. // TE_ADDRESS - AE_FORWARD
  916. // Address level
  917. GetSubEventFlag(TE_ADDRESS, AE_FORWARD, &bEnable);
  918. if( bEnable )
  919. {
  920. dwAddrStateSubMasks |= LINEADDRESSSTATE_FORWARD;
  921. }
  922. return dwAddrStateSubMasks;
  923. }
  924. /*++
  925. SetTapiSrvAddressEventMask
  926. Set the event mask to the TapiSrv level for an address
  927. It's called immediatly after we open a line
  928. --*/
  929. HRESULT CEventMasks::SetTapiSrvAddressEventMask(
  930. IN HLINE hLine
  931. )
  932. {
  933. LOG((TL_TRACE, "SetTapiSrvAddressEventMask - Enter"));
  934. HRESULT hr = E_FAIL;
  935. //
  936. // Get the TapiSrvEvent masks
  937. //
  938. ULONG64 ulEventMasks = 0;
  939. DWORD dwLineDevStateSubMasks = 0;
  940. DWORD dwAddrStateSubMasks = 0;
  941. ulEventMasks = GetTapiSrvEventMask(
  942. FALSE // Address level
  943. );
  944. LOG((TL_INFO, "GetTapiSrvEventMask returns %x",
  945. ulEventMasks));
  946. dwLineDevStateSubMasks = GetTapiSrvLineStateMask();
  947. LOG((TL_INFO, "GetTapiSrvLineStateMask returns %x",
  948. dwLineDevStateSubMasks));
  949. dwAddrStateSubMasks = GetTapiSrvAddrStateMask();
  950. LOG((TL_INFO, "GetTapiSrvAddrStateMask returns %x",
  951. dwAddrStateSubMasks));
  952. hr = tapiSetEventFilterMasks (
  953. TAPIOBJ_HLINE,
  954. hLine,
  955. ulEventMasks
  956. );
  957. if (hr == 0)
  958. {
  959. hr = tapiSetEventFilterSubMasks (
  960. TAPIOBJ_HLINE,
  961. hLine,
  962. EM_LINE_LINEDEVSTATE,
  963. dwLineDevStateSubMasks
  964. );
  965. }
  966. if (hr == 0)
  967. {
  968. hr = tapiSetEventFilterSubMasks (
  969. TAPIOBJ_HLINE,
  970. hLine,
  971. EM_LINE_ADDRESSSTATE,
  972. dwAddrStateSubMasks
  973. );
  974. }
  975. if (hr != 0)
  976. {
  977. hr = mapTAPIErrorCode(hr);
  978. LOG((TL_ERROR,
  979. "CEventMasks::SetTapiSrvAddressEventMask - failed TapiSrv 0x%08x", hr));
  980. // Leave critical section
  981. return hr;
  982. }
  983. LOG((TL_TRACE, "SetTapiSrvAddressEventMask - Exit 0x%08x", hr));
  984. return hr;
  985. }
  986. HRESULT CEventMasks::SetTapiSrvCallEventMask(
  987. IN HCALL hCall
  988. )
  989. {
  990. LOG((TL_TRACE, "SetTapiSrvCallEventMask - Enter. call handle[%lx]", hCall));
  991. HRESULT hr = E_FAIL;
  992. //
  993. // Get the TapiSrvEvent masks
  994. //
  995. ULONG64 ulEventMasks = 0;
  996. ulEventMasks = GetTapiSrvEventMask(
  997. TRUE // Call level
  998. );
  999. LOG((TL_INFO, "GetTapiSrvEventMask returns %x",
  1000. ulEventMasks));
  1001. hr = tapiSetEventFilterMasks (
  1002. TAPIOBJ_HCALL,
  1003. hCall,
  1004. ulEventMasks
  1005. );
  1006. if (hr != 0)
  1007. {
  1008. LOG((TL_ERROR,
  1009. "CEventMasks::SetTapiSrvCallEventMaskr - TapiSrv failed 0x%08x", hr));
  1010. return hr;
  1011. }
  1012. LOG((TL_TRACE, "SetTapiSrvCallEventMask - Exit 0x%08x", hr));
  1013. return hr;
  1014. }
  1015. //
  1016. // ITAddress methods
  1017. //
  1018. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1019. //
  1020. // get_State
  1021. //
  1022. // retries the current ADDRESS_STATE of the address
  1023. //
  1024. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1025. HRESULT
  1026. STDMETHODCALLTYPE
  1027. CAddress::get_State(
  1028. ADDRESS_STATE * pAddressState
  1029. )
  1030. {
  1031. HRESULT hr = S_OK;
  1032. LOG((TL_TRACE, "get_State enter" ));
  1033. if (TAPIIsBadWritePtr( pAddressState, sizeof( ADDRESS_STATE ) ) )
  1034. {
  1035. LOG((TL_ERROR, "get_State - bad pointer"));
  1036. return E_POINTER;
  1037. }
  1038. Lock();
  1039. *pAddressState = m_AddressState;
  1040. Unlock();
  1041. LOG((TL_TRACE, "get_State exit - return %lx", hr));
  1042. return hr;
  1043. }
  1044. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1045. //
  1046. // GetAddressName
  1047. // Copy address name to ppName
  1048. // The application must free the name returned through sysfreestirng.
  1049. //
  1050. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1051. HRESULT
  1052. STDMETHODCALLTYPE
  1053. CAddress::get_AddressName(
  1054. BSTR * ppName
  1055. )
  1056. {
  1057. HRESULT hr = S_OK;
  1058. LOG((TL_TRACE, "get_AddressName enter" ));
  1059. LOG((TL_TRACE, " ppName --------->%p", ppName ));
  1060. if ( TAPIIsBadWritePtr( ppName, sizeof( BSTR ) ) )
  1061. {
  1062. LOG((TL_ERROR, "get_AddressName - bad pointer"));
  1063. return E_POINTER;
  1064. }
  1065. Lock();
  1066. if ( m_dwAddressFlags & ADDRESSFLAG_DEVCAPSCHANGE )
  1067. {
  1068. hr = UpdateLineDevCaps();
  1069. if ( SUCCEEDED(hr) )
  1070. {
  1071. hr = SaveAddressName( m_pDevCaps );
  1072. }
  1073. m_dwAddressFlags &= ~ADDRESSFLAG_DEVCAPSCHANGE;
  1074. }
  1075. *ppName = SysAllocString(
  1076. m_szAddressName
  1077. );
  1078. Unlock();
  1079. if (NULL == *ppName)
  1080. {
  1081. LOG((TL_ERROR, "get_AddressName exit - return E_OUTOFMEMORY"));
  1082. return E_OUTOFMEMORY;
  1083. }
  1084. LOG((TL_TRACE, "get_AddressName exit - return %lx", hr ));
  1085. return hr;
  1086. }
  1087. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1088. //
  1089. // get_ServiceProviderName
  1090. // Get the name of the service provider that owns this line/
  1091. // address.
  1092. // Note that we don't get the name on startup - we only get
  1093. // it if it is requested. This shouldn't be used too often.
  1094. //
  1095. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1096. HRESULT
  1097. STDMETHODCALLTYPE
  1098. CAddress::get_ServiceProviderName(
  1099. BSTR * ppName
  1100. )
  1101. {
  1102. HRESULT hr = S_OK;
  1103. LPVARSTRING pVarString = NULL;
  1104. DWORD dwProviderID;
  1105. LPLINEPROVIDERLIST pProviderList = NULL;
  1106. LOG((TL_TRACE, "get_ServiceProviderName enter" ));
  1107. if (TAPIIsBadWritePtr( ppName, sizeof( BSTR ) ) )
  1108. {
  1109. LOG((TL_ERROR, "get_ServiceProviderName - bad pointer"));
  1110. return E_POINTER;
  1111. }
  1112. Lock();
  1113. //
  1114. // if we have already determined the sp name,
  1115. // just return it.
  1116. //
  1117. if (NULL != m_szProviderName)
  1118. {
  1119. *ppName = SysAllocString( m_szProviderName );
  1120. Unlock();
  1121. if (NULL == *ppName)
  1122. {
  1123. LOG((TL_ERROR, "get_ServiceProviderName - alloc ppName failed" ));
  1124. return E_OUTOFMEMORY;
  1125. }
  1126. LOG((TL_TRACE, "get_ServiceProviderName - exit - return SUCCESS" ));
  1127. return S_OK;
  1128. }
  1129. Unlock();
  1130. //
  1131. // get the provider list
  1132. //
  1133. hr = LineGetProviderList(
  1134. &pProviderList
  1135. );
  1136. if (S_OK != hr)
  1137. {
  1138. if (NULL != pProviderList )
  1139. {
  1140. ClientFree( pProviderList );
  1141. }
  1142. LOG((TL_ERROR, "get_ServiceProvideName - LineGetProviderList returned %lx", hr ));
  1143. return hr;
  1144. }
  1145. LPLINEPROVIDERENTRY pProvEntry;
  1146. PWSTR pszProviderName;
  1147. DWORD dwCount;
  1148. hr = S_OK;
  1149. pProvEntry = (LPLINEPROVIDERENTRY)( ( (LPBYTE) pProviderList ) + pProviderList->dwProviderListOffset );
  1150. Lock();
  1151. //
  1152. // make sure the name was not set by another thread while we were waiting
  1153. // for the lock. if it was, do nothing.
  1154. //
  1155. if (NULL == m_szProviderName)
  1156. {
  1157. //
  1158. // search through the list for the provider id, until done with all
  1159. // providers or encounter an error
  1160. //
  1161. for ( dwCount = 0; dwCount < pProviderList->dwNumProviders; dwCount++ )
  1162. {
  1163. if (pProvEntry->dwPermanentProviderID == m_dwProviderID)
  1164. {
  1165. //
  1166. // it's a match! copy the name, if we can.
  1167. //
  1168. m_szProviderName = (PWSTR)ClientAlloc( pProvEntry->dwProviderFilenameSize + sizeof(WCHAR) );
  1169. if (NULL == m_szProviderName)
  1170. {
  1171. LOG((TL_ERROR, "get_ServiceProviderName - alloc m_szProviderName failed" ));
  1172. hr = E_OUTOFMEMORY;
  1173. }
  1174. else
  1175. {
  1176. //
  1177. // save it in the object
  1178. //
  1179. memcpy(
  1180. m_szProviderName,
  1181. ((LPBYTE)pProviderList) + pProvEntry->dwProviderFilenameOffset,
  1182. pProvEntry->dwProviderFilenameSize
  1183. );
  1184. }
  1185. //
  1186. // found a match. m_szProviderName contains the string, or hr
  1187. // contains the error if failed.
  1188. //
  1189. break;
  1190. }
  1191. pProvEntry++;
  1192. }
  1193. //
  1194. // did we find it?
  1195. //
  1196. if (dwCount == pProviderList->dwNumProviders)
  1197. {
  1198. LOG((TL_ERROR, "get_ServiceProviderName - could not find provider in list" ));
  1199. //
  1200. // if we looped through the whole list but did not find a match, hr
  1201. // should still be S_OK
  1202. //
  1203. // assert to protect from future code changes erroneously
  1204. // overwritingthe error code.
  1205. //
  1206. _ASSERTE(SUCCEEDED(hr));
  1207. //
  1208. // couldn't find the provider.
  1209. //
  1210. hr = TAPI_E_NODRIVER;
  1211. }
  1212. } // if (NULL == m_szProviderName)
  1213. //
  1214. // if hr does not contain an error, the m_szProviderName must contain a
  1215. // valid string
  1216. //
  1217. if (SUCCEEDED(hr))
  1218. {
  1219. _ASSERTE( NULL != m_szProviderName );
  1220. *ppName = SysAllocString( m_szProviderName );
  1221. if (NULL == *ppName)
  1222. {
  1223. //
  1224. // could not allocated string
  1225. //
  1226. LOG((TL_ERROR,
  1227. "get_ServiceProviderName - failed to allocate memory for provider name string" ));
  1228. hr = E_OUTOFMEMORY;
  1229. }
  1230. }
  1231. Unlock();
  1232. ClientFree( pProviderList );
  1233. LOG((TL_TRACE, "get_ServiceProviderName exit - return %lx", hr));
  1234. return hr;
  1235. }
  1236. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1237. //
  1238. // get_TAPIObject
  1239. //
  1240. // return the owning tapi object
  1241. //
  1242. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1243. HRESULT
  1244. STDMETHODCALLTYPE
  1245. CAddress::get_TAPIObject(
  1246. ITTAPI ** ppTapiObject
  1247. )
  1248. {
  1249. HRESULT hr = S_OK;
  1250. LOG((TL_TRACE, "get_TAPIObject enter" ));
  1251. if (TAPIIsBadWritePtr( ppTapiObject, sizeof( ITTAPI * ) ) )
  1252. {
  1253. LOG((TL_ERROR, "get_TAPIObject - bad pointer"));
  1254. return E_POINTER;
  1255. }
  1256. *ppTapiObject = m_pTAPI;
  1257. m_pTAPI->AddRef();
  1258. LOG((TL_TRACE, "get_TAPIObject exit - return %lx", hr ));
  1259. return hr;
  1260. }
  1261. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1262. //
  1263. // GetTapi
  1264. //
  1265. // private method to get the tapi object
  1266. //
  1267. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1268. CTAPI *
  1269. CAddress::GetTapi(BOOL bAddRefTapi)
  1270. {
  1271. CTAPI * p = NULL;
  1272. Lock();
  1273. //
  1274. // get a pointer to tapi object
  1275. //
  1276. if( m_pTAPI != NULL )
  1277. {
  1278. p = dynamic_cast<CTAPI *>(m_pTAPI);
  1279. }
  1280. //
  1281. // addref tapi if needed and if possible
  1282. //
  1283. if ( (NULL != p) && bAddRefTapi)
  1284. {
  1285. //
  1286. // we have an object and we need to addref it before returing
  1287. //
  1288. p->AddRef();
  1289. }
  1290. Unlock();
  1291. LOG((TL_TRACE, "GetTapi - returning [%p]", p));
  1292. return p;
  1293. }
  1294. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1295. //
  1296. // InternalCreateCall
  1297. //
  1298. // called by a couple of places to create a call.
  1299. //
  1300. // pszDestAddress
  1301. // destaddress of the call
  1302. //
  1303. // cp
  1304. // current call privilege
  1305. //
  1306. // hCall
  1307. // tapi2 call handle
  1308. //
  1309. // bExpose
  1310. // is this a hidden call?
  1311. //
  1312. // ppCall
  1313. // return call object here
  1314. //
  1315. //
  1316. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1317. HRESULT
  1318. CAddress::InternalCreateCall(
  1319. PWSTR pszDestAddress,
  1320. long lAddressType,
  1321. long lMediaType,
  1322. CALL_PRIVILEGE cp,
  1323. BOOL bNeedToNotify,
  1324. HCALL hCall,
  1325. BOOL bExpose,
  1326. CCall ** ppCall
  1327. )
  1328. {
  1329. HRESULT hr;
  1330. LOG((TL_TRACE, "InternalCreateCall enter" ));
  1331. //
  1332. // create & initialize a new call object
  1333. //
  1334. CComObject<CCall> * pCall;
  1335. hr = CComObject<CCall>::CreateInstance( &pCall );
  1336. if (NULL == pCall)
  1337. {
  1338. LOG((TL_ERROR, "InternalCreateCall - could not create call instance" ));
  1339. return E_OUTOFMEMORY;
  1340. }
  1341. //
  1342. // initialize the call object.
  1343. //
  1344. // note: getting address lock while initializing a
  1345. // call object can lead to deadlocks
  1346. //
  1347. hr = pCall->Initialize(
  1348. this,
  1349. pszDestAddress,
  1350. lAddressType,
  1351. lMediaType,
  1352. cp,
  1353. bNeedToNotify,
  1354. bExpose,
  1355. hCall,
  1356. &m_EventMasks
  1357. );
  1358. if (S_OK != hr)
  1359. {
  1360. delete pCall;
  1361. LOG((TL_ERROR, "InternalCreateCall failed - Call object failed init - %lx", hr ));
  1362. return hr;
  1363. }
  1364. //
  1365. // serialize call creation with call cleanup (which happens when tapi tells
  1366. // us it is being shutdown).
  1367. //
  1368. Lock();
  1369. //
  1370. // tapi object already signaled shutdown?
  1371. //
  1372. if (m_bTapiSignaledShutdown)
  1373. {
  1374. Unlock();
  1375. //
  1376. // tapi object already notified us of its shutdown and we already did
  1377. // cleanup. no need to create any new calls
  1378. //
  1379. LOG((TL_ERROR,
  1380. "InternalCreateCall - tapi object shut down. cannot create call" ));
  1381. //
  1382. // we have no use for the call object
  1383. //
  1384. pCall->Release();
  1385. if (bNeedToNotify)
  1386. {
  1387. //
  1388. // compensate for the extra refcount added if bNeedToNotify is on
  1389. //
  1390. pCall->Release();
  1391. }
  1392. pCall = NULL;
  1393. return TAPI_E_WRONG_STATE;
  1394. }
  1395. if (bExpose)
  1396. {
  1397. ITCallInfo * pITCallInfo;
  1398. pITCallInfo = dynamic_cast<ITCallInfo *>(pCall);
  1399. //
  1400. // save the call in this address's list
  1401. //
  1402. hr = AddCall( pITCallInfo );
  1403. }
  1404. //
  1405. // the call was created and initialized, it is now safe for call cleanup
  1406. // logic to kick in if it was waiting for the lock
  1407. //
  1408. Unlock();
  1409. //
  1410. // return it
  1411. //
  1412. *ppCall = pCall;
  1413. LOG((TL_TRACE, "InternalCreateCall exit - return S_OK" ));
  1414. return S_OK;
  1415. }
  1416. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1417. //
  1418. // CreateCall
  1419. //
  1420. // An application calls this method to create an outgoing call object
  1421. //
  1422. // lpszDestAddress
  1423. // DestAddress of the call
  1424. //
  1425. // ppCall
  1426. // return call object here
  1427. //
  1428. //
  1429. // returns
  1430. //
  1431. //
  1432. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1433. HRESULT
  1434. STDMETHODCALLTYPE
  1435. CAddress::CreateCall(
  1436. BSTR lpszDestAddress,
  1437. long lAddressType,
  1438. long lMediaType,
  1439. ITBasicCallControl ** ppCall
  1440. )
  1441. {
  1442. HRESULT hr;
  1443. CCall * pCall;
  1444. LOG((TL_TRACE, "CreateCall enter" ));
  1445. if (TAPIIsBadWritePtr( ppCall, sizeof(ITBasicCallControl *) ) )
  1446. {
  1447. LOG((TL_ERROR, "CreateCall - bad pointer"));
  1448. return E_POINTER;
  1449. }
  1450. if ((lpszDestAddress != NULL) && IsBadStringPtrW( lpszDestAddress, -1 )) // NULL is ok
  1451. {
  1452. LOG((TL_ERROR, "CreateCall - bad string"));
  1453. return E_POINTER;
  1454. }
  1455. //
  1456. // use internal function
  1457. //
  1458. hr = InternalCreateCall(
  1459. lpszDestAddress,
  1460. lAddressType,
  1461. lMediaType,
  1462. CP_OWNER,
  1463. FALSE,
  1464. NULL,
  1465. TRUE,
  1466. &pCall
  1467. );
  1468. if (S_OK != hr)
  1469. {
  1470. LOG((TL_ERROR, "CreateCall - InternalCreateCall failed hr = %lx", hr));
  1471. return hr;
  1472. }
  1473. //
  1474. // put result in out pointer - also
  1475. // increments the ref count
  1476. //
  1477. hr = pCall->QueryInterface(
  1478. IID_ITBasicCallControl,
  1479. (void **) ppCall
  1480. );
  1481. //
  1482. // internalcreatecall has a reference - don't keep it
  1483. //
  1484. pCall->Release();
  1485. if (S_OK != hr)
  1486. {
  1487. LOG((TL_ERROR, "CreateCall - saving call failed" ));
  1488. return hr;
  1489. }
  1490. LOG((TL_TRACE, "CreateCall exit - return SUCCESS" ));
  1491. return S_OK;
  1492. }
  1493. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1494. //
  1495. // get_Calls
  1496. // return a collection of calls that this address currently
  1497. // owns
  1498. //
  1499. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1500. HRESULT
  1501. STDMETHODCALLTYPE
  1502. CAddress::get_Calls(
  1503. VARIANT * pVariant
  1504. )
  1505. {
  1506. HRESULT hr;
  1507. IDispatch * pDisp;
  1508. LOG((TL_TRACE, "get_Calls enter" ));
  1509. if (TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) )
  1510. {
  1511. LOG((TL_ERROR, "get_Calls - bad pointer"));
  1512. return E_POINTER;
  1513. }
  1514. CComObject< CTapiCollection< ITCallInfo > > * p;
  1515. CComObject< CTapiCollection< ITCallInfo > >::CreateInstance( &p );
  1516. if (NULL == p)
  1517. {
  1518. LOG((TL_ERROR, "get_Calls - could not create collection" ));
  1519. return E_OUTOFMEMORY;
  1520. }
  1521. Lock();
  1522. // initialize
  1523. hr = p->Initialize( m_CallArray );
  1524. Unlock();
  1525. if (S_OK != hr)
  1526. {
  1527. LOG((TL_ERROR, "get_Calls - could not initialize collection" ));
  1528. delete p;
  1529. return hr;
  1530. }
  1531. // get the IDispatch interface
  1532. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  1533. if (S_OK != hr)
  1534. {
  1535. LOG((TL_ERROR, "get_Calls - could not get IDispatch interface" ));
  1536. delete p;
  1537. return hr;
  1538. }
  1539. // put it in the variant
  1540. VariantInit(pVariant);
  1541. pVariant->vt = VT_DISPATCH;
  1542. pVariant->pdispVal = pDisp;
  1543. LOG((TL_TRACE, "get_Calls - exit - return %lx", hr ));
  1544. return hr;
  1545. }
  1546. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1547. //
  1548. // EnumerateCalls
  1549. // returns an enumeration of calls the this address currently owns
  1550. //
  1551. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1552. HRESULT
  1553. STDMETHODCALLTYPE
  1554. CAddress::EnumerateCalls(
  1555. IEnumCall ** ppCallEnum
  1556. )
  1557. {
  1558. HRESULT hr = S_OK;
  1559. LOG((TL_TRACE, "EnumerateCalls enter" ));
  1560. LOG((TL_TRACE, " ppCallEnum----->%p", ppCallEnum ));
  1561. if (TAPIIsBadWritePtr(ppCallEnum, sizeof( ppCallEnum ) ) )
  1562. {
  1563. LOG((TL_ERROR, "EnumerateCalls - bad pointer"));
  1564. return E_POINTER;
  1565. }
  1566. //
  1567. // create the enumerator
  1568. //
  1569. CComObject< CTapiEnum< IEnumCall, ITCallInfo, &IID_IEnumCall > > * p;
  1570. hr = CComObject< CTapiEnum< IEnumCall, ITCallInfo, &IID_IEnumCall > >
  1571. ::CreateInstance( &p );
  1572. if (S_OK != hr)
  1573. {
  1574. LOG((TL_ERROR, "EnumerateCalls - could not create enum" ));
  1575. return hr;
  1576. }
  1577. Lock();
  1578. //
  1579. // initialize it with our call list
  1580. //
  1581. p->Initialize( m_CallArray );
  1582. Unlock();
  1583. //
  1584. // return it
  1585. //
  1586. *ppCallEnum = p;
  1587. LOG((TL_TRACE, "EnumerateCalls exit - return %lx", hr ));
  1588. return hr;
  1589. }
  1590. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1591. //
  1592. // FinalRelease
  1593. // Clean up anything in the address object.
  1594. //
  1595. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1596. void CAddress::FinalRelease()
  1597. {
  1598. CTAPI * pCTapi;
  1599. LOG((TL_TRACE, "FinalRelease[%p] - enter", this));
  1600. Lock();
  1601. // remove from the handle hash table, so any more messages
  1602. // from msp callback events are ignored
  1603. //
  1604. RemoveHandleFromHashTable(m_MSPContext);
  1605. m_MSPContext = NULL;
  1606. pCTapi = GetTapi();
  1607. if( NULL == pCTapi )
  1608. {
  1609. LOG((TL_ERROR, "dynamic cast operation failed"));
  1610. }
  1611. else
  1612. {
  1613. pCTapi->InvalidateBuffer( BUFFERTYPE_LINEDEVCAP, (UINT_PTR)this );
  1614. pCTapi->InvalidateBuffer( BUFFERTYPE_ADDRCAP, (UINT_PTR)this );
  1615. }
  1616. if ( NULL != m_szAddress )
  1617. {
  1618. ClientFree( m_szAddress);
  1619. m_szAddress = NULL;
  1620. }
  1621. if ( NULL != m_szAddressName)
  1622. {
  1623. LOG((TL_INFO, "FinalRelease - m_szAddressName is [%ls]", m_szAddressName ));
  1624. ClientFree( m_szAddressName );
  1625. m_szAddressName = NULL;
  1626. }
  1627. if ( NULL != m_szProviderName )
  1628. {
  1629. ClientFree( m_szProviderName );
  1630. m_szProviderName = NULL;
  1631. }
  1632. //
  1633. // release calls
  1634. //
  1635. m_CallArray.Shutdown();
  1636. //
  1637. // release terminals
  1638. //
  1639. m_TerminalArray.Shutdown();
  1640. //
  1641. // release addresslines
  1642. //
  1643. PtrList::iterator l;
  1644. for (l = m_AddressLinesPtrList.begin(); l != m_AddressLinesPtrList.end(); l++)
  1645. {
  1646. HRESULT hr;
  1647. AddressLineStruct * pLine;
  1648. pLine = (AddressLineStruct *)(*l);
  1649. if (pLine == m_pCallHubTrackingLine)
  1650. {
  1651. // this line is used for call hub tracking
  1652. // make sure we don't try and delete this again below
  1653. m_pCallHubTrackingLine = NULL;
  1654. }
  1655. LineClose(
  1656. &(pLine->t3Line)
  1657. );
  1658. ClientFree (pLine);
  1659. }
  1660. if (m_pCallHubTrackingLine != NULL)
  1661. {
  1662. LineClose( &(m_pCallHubTrackingLine->t3Line) );
  1663. }
  1664. //
  1665. // free the msp
  1666. //
  1667. if ( NULL != m_pMSPAggAddress )
  1668. {
  1669. ITMSPAddress * pMSPAddress = GetMSPAddress();
  1670. pMSPAddress->Shutdown();
  1671. pMSPAddress->Release();
  1672. m_pMSPAggAddress->Release();
  1673. m_pMSPAggAddress = NULL;
  1674. }
  1675. //
  1676. // unregister the msp wait
  1677. // event in the thread pool
  1678. //
  1679. if ( NULL != m_hWaitEvent )
  1680. {
  1681. LOG((TL_TRACE, "FinalRelease - unregistering callback"));
  1682. UnregisterWaitEx( m_hWaitEvent, INVALID_HANDLE_VALUE);
  1683. m_hWaitEvent = NULL;
  1684. }
  1685. //
  1686. // close the msp event
  1687. //
  1688. if ( NULL != m_hMSPEvent )
  1689. {
  1690. CloseHandle(m_hMSPEvent );
  1691. }
  1692. //
  1693. // release the private object
  1694. //
  1695. if ( NULL != m_pPrivate )
  1696. {
  1697. m_pPrivate->Release();
  1698. }
  1699. m_pTAPI->Release();
  1700. m_pTAPI = NULL;
  1701. Unlock();
  1702. LOG((TL_TRACE, "FinalRelease - exit"));
  1703. }
  1704. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1705. //
  1706. // CreateWaveMSPObject
  1707. //
  1708. // special case - creates the wavemsp object
  1709. //
  1710. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1711. HRESULT
  1712. CreateWaveMSPObject(
  1713. IUnknown * pUnk,
  1714. IUnknown ** ppMSPAggAddress
  1715. )
  1716. {
  1717. HRESULT hr = S_OK;
  1718. LOG((TL_TRACE, "CreateWaveMSPObject - enter"));
  1719. hr = CoCreateInstance(
  1720. CLSID_WAVEMSP,
  1721. pUnk,
  1722. CLSCTX_INPROC_SERVER,
  1723. IID_IUnknown,
  1724. (void **) ppMSPAggAddress
  1725. );
  1726. if (!SUCCEEDED(hr))
  1727. {
  1728. LOG((TL_ERROR, "CreateWaveMSPObject failed to CoCreate - %lx", hr));
  1729. return hr;
  1730. }
  1731. LOG((TL_TRACE, "CreateWaveMSPObject - exit"));
  1732. return hr;
  1733. }
  1734. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1735. //
  1736. // CreateWaveInfo
  1737. //
  1738. // for a wave device address, get the wave device IDs to give
  1739. // to the wavemsp
  1740. //
  1741. // First DWORD = Command Second DWORD Third DWORD
  1742. // 0 Set wave IDs for call WaveIn ID WaveOut ID
  1743. // 1 Start streaming <ignored> <ignored>
  1744. // 2 Stop streaming <ignored> <ignored>
  1745. // 3 Set wave IDs for address WaveIn ID WaveOut ID
  1746. // 4 Wave IDS for address not available
  1747. // 5 stop streaming because a blocking tapi functions was called
  1748. // 6
  1749. // 7
  1750. // 8 full duplex support
  1751. //
  1752. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  1753. HRESULT
  1754. CreateWaveInfo(
  1755. HLINE hLine,
  1756. DWORD dwAddressID,
  1757. HCALL hCall,
  1758. DWORD dwCallSelect,
  1759. BOOL bFullDuplex,
  1760. LPDWORD pdwIDs
  1761. )
  1762. {
  1763. LPVARSTRING pVarString;
  1764. HRESULT hr;
  1765. if ( bFullDuplex )
  1766. {
  1767. hr = LineGetID(
  1768. hLine,
  1769. dwAddressID,
  1770. hCall,
  1771. dwCallSelect,
  1772. &pVarString,
  1773. L"wave/in/out"
  1774. );
  1775. if (!SUCCEEDED(hr))
  1776. {
  1777. if (NULL != pVarString)
  1778. {
  1779. ClientFree( pVarString );
  1780. }
  1781. LOG((TL_ERROR, "LineGetID failed for waveinout device - %lx", hr ));
  1782. return hr;
  1783. }
  1784. pdwIDs[1] = ((LPDWORD)(pVarString+1))[0];
  1785. pdwIDs[2] = ((LPDWORD)(pVarString+1))[1];
  1786. ClientFree( pVarString );
  1787. return S_OK;
  1788. }
  1789. //
  1790. // get the wave/in id
  1791. //
  1792. hr = LineGetID(
  1793. hLine,
  1794. dwAddressID,
  1795. hCall,
  1796. dwCallSelect,
  1797. &pVarString,
  1798. L"wave/in"
  1799. );
  1800. if (!SUCCEEDED(hr))
  1801. {
  1802. if (NULL != pVarString)
  1803. {
  1804. ClientFree( pVarString );
  1805. }
  1806. LOG((TL_ERROR, "LineGetID failed for wavein device - %lx", hr ));
  1807. return hr;
  1808. }
  1809. //
  1810. // saveit
  1811. //
  1812. pdwIDs[1] = *((LPDWORD)(pVarString+1));
  1813. ClientFree( pVarString );
  1814. //
  1815. // get the waveout id
  1816. //
  1817. hr = LineGetID(
  1818. hLine,
  1819. dwAddressID,
  1820. hCall,
  1821. dwCallSelect,
  1822. &pVarString,
  1823. L"wave/out"
  1824. );
  1825. if (!SUCCEEDED(hr))
  1826. {
  1827. if (NULL != pVarString)
  1828. {
  1829. ClientFree( pVarString );
  1830. }
  1831. LOG((TL_ERROR, "LineGetID failed for waveout device - %lx", hr ));
  1832. return hr;
  1833. }
  1834. //
  1835. // save it
  1836. //
  1837. pdwIDs[2] = *((LPDWORD)(pVarString+1));
  1838. ClientFree( pVarString );
  1839. return S_OK;
  1840. }
  1841. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1842. //
  1843. //
  1844. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1845. HRESULT
  1846. CAddress::InitializeWaveDeviceIDs( HLINE hLine )
  1847. {
  1848. DWORD adwIDs[3];
  1849. HRESULT hr;
  1850. hr = CreateWaveInfo(
  1851. hLine,
  1852. GetAddressID(),
  1853. NULL,
  1854. LINECALLSELECT_ADDRESS,
  1855. HasFullDuplexWaveDevice(),
  1856. adwIDs
  1857. );
  1858. if ( SUCCEEDED(hr) )
  1859. {
  1860. adwIDs[0] = 3;
  1861. }
  1862. else
  1863. {
  1864. adwIDs[0] = 4;
  1865. }
  1866. hr = ReceiveTSPData(
  1867. NULL,
  1868. (LPBYTE)adwIDs,
  1869. sizeof(adwIDs)
  1870. );
  1871. if ( TAPI_VERSION3_0 <= m_dwAPIVersion )
  1872. {
  1873. adwIDs[0] = 8;
  1874. if ( m_dwAddressFlags & ADDRESSFLAG_WAVEFULLDUPLEX )
  1875. {
  1876. adwIDs[1] = 1;
  1877. }
  1878. else
  1879. {
  1880. adwIDs[1] = 0;
  1881. }
  1882. hr = ReceiveTSPData(
  1883. NULL,
  1884. (LPBYTE)adwIDs,
  1885. sizeof(adwIDs)
  1886. );
  1887. }
  1888. return hr;
  1889. }
  1890. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1891. //
  1892. // SaveAddressName
  1893. //
  1894. // saves the address name based on the linename in devcaps
  1895. //
  1896. // called in lock
  1897. //
  1898. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1899. HRESULT
  1900. CAddress::SaveAddressName( LPLINEDEVCAPS pDevCaps )
  1901. {
  1902. PWSTR pAddressName = NULL;
  1903. PWSTR pAddressString = NULL;
  1904. DWORD dwAddressStringSize = 0;
  1905. //
  1906. // save the line name
  1907. //
  1908. if ( pDevCaps->dwNumAddresses > 1 )
  1909. {
  1910. pAddressString = MyLoadString( IDS_ADDRESS );
  1911. if ( NULL == pAddressString )
  1912. {
  1913. return E_UNEXPECTED;
  1914. }
  1915. dwAddressStringSize = (lstrlenW( pAddressString ) + 1) * sizeof(WCHAR);
  1916. //
  1917. // need to add some room for whitespace
  1918. //
  1919. dwAddressStringSize += 10 * sizeof(WCHAR);
  1920. }
  1921. if (0 != pDevCaps->dwLineNameSize)
  1922. {
  1923. DWORD dwSize;
  1924. dwSize = pDevCaps->dwLineNameSize + sizeof(WCHAR);
  1925. dwSize += dwAddressStringSize;
  1926. pAddressName = (PWSTR) ClientAlloc(dwSize);
  1927. if (NULL == pAddressName)
  1928. {
  1929. LOG((TL_ERROR, "Initialize - alloc pAddressName failed" ));
  1930. if ( NULL != pAddressString )
  1931. {
  1932. ClientFree( pAddressString );
  1933. }
  1934. return E_OUTOFMEMORY;
  1935. }
  1936. memcpy(
  1937. pAddressName,
  1938. ((LPBYTE)(pDevCaps)) + pDevCaps->dwLineNameOffset,
  1939. pDevCaps->dwLineNameSize
  1940. );
  1941. }
  1942. else
  1943. {
  1944. PWSTR pTempBuffer;
  1945. DWORD dwSize = 0;
  1946. pTempBuffer = MyLoadString( IDS_LINE );
  1947. if ( NULL == pTempBuffer )
  1948. {
  1949. LOG((TL_ERROR, "Initialize - couldn't load LINE resource"));
  1950. if ( NULL != pAddressString )
  1951. {
  1952. ClientFree( pAddressString );
  1953. }
  1954. return E_UNEXPECTED;
  1955. }
  1956. dwSize = (lstrlenW( pTempBuffer ) + 1) * sizeof(WCHAR);
  1957. dwSize += dwAddressStringSize;
  1958. //
  1959. // need some whitespace
  1960. //
  1961. dwSize += 5 * sizeof(WCHAR);
  1962. pAddressName = (PWSTR) ClientAlloc( dwSize );
  1963. if ( NULL == pAddressName )
  1964. {
  1965. ClientFree( pTempBuffer );
  1966. if ( NULL != pAddressString )
  1967. {
  1968. ClientFree( pAddressString );
  1969. }
  1970. return E_OUTOFMEMORY;
  1971. }
  1972. wsprintfW(
  1973. pAddressName,
  1974. L"%s %d",
  1975. pTempBuffer,
  1976. m_dwDeviceID
  1977. );
  1978. ClientFree( pTempBuffer );
  1979. }
  1980. //
  1981. // append the address # if there is more than one address on the line
  1982. //
  1983. if (pDevCaps->dwNumAddresses > 1)
  1984. {
  1985. wsprintfW(
  1986. pAddressName,
  1987. L"%s - %s %d",
  1988. pAddressName,
  1989. pAddressString,
  1990. m_dwAddressID
  1991. );
  1992. }
  1993. if ( NULL != pAddressString )
  1994. {
  1995. ClientFree( pAddressString );
  1996. }
  1997. if ( NULL != m_szAddressName )
  1998. {
  1999. ClientFree( m_szAddressName);
  2000. }
  2001. m_szAddressName = pAddressName;
  2002. return S_OK;
  2003. }
  2004. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2005. //
  2006. // Initialize
  2007. // Init the CAddress object
  2008. //
  2009. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2010. HRESULT
  2011. CAddress::Initialize(
  2012. ITTAPI * pTapi,
  2013. HLINEAPP hLineApp,
  2014. #ifdef USE_PHONEMSP
  2015. HPHONEAPP hPhoneApp,
  2016. #endif USE_PHONEMSP
  2017. DWORD dwAPIVersion,
  2018. DWORD dwDeviceID,
  2019. DWORD dwAddressID,
  2020. DWORD dwProviderID,
  2021. LPLINEDEVCAPS pDevCaps,
  2022. DWORD dwEventFilterMask
  2023. )
  2024. {
  2025. LONG lResult;
  2026. HRESULT hr;
  2027. T3LINE t3Line;
  2028. #ifdef USE_PHONEMSP
  2029. BOOL bPreferPhoneMSPForProvider = FALSE;
  2030. #endif USE_PHONEMSP
  2031. t3Line.hLine = NULL;
  2032. t3Line.dwAddressLineStructHandle = 0;
  2033. LOG((TL_TRACE, "Initialize[%p] enter", this ));
  2034. LOG((TL_INFO, " hLineApp ---------->%lx", hLineApp ));
  2035. #ifdef USE_PHONEMSP
  2036. LOG((TL_INFO, " hPhoneApp --------->%lx", hPhoneApp ));
  2037. #endif USE_PHONEMSP
  2038. LOG((TL_INFO, " dwAPIVersion ------>%lx", dwAPIVersion ));
  2039. LOG((TL_INFO, " dwDeviceID -------->%lx", dwDeviceID ));
  2040. LOG((TL_INFO, " dwAddressID ------->%lx", dwAddressID ));
  2041. LOG((TL_INFO, " pDevCaps ---------->%p", pDevCaps ));
  2042. Lock();
  2043. //
  2044. // save relevant info
  2045. //
  2046. m_pTAPI = pTapi;
  2047. m_dwDeviceID = dwDeviceID;
  2048. m_dwAddressID = dwAddressID;
  2049. m_dwMediaModesSupported = pDevCaps->dwMediaModes;
  2050. m_hLineApp = hLineApp;
  2051. #ifdef USE_PHONEMSP
  2052. m_hPhoneApp = hPhoneApp;
  2053. #endif USE_PHONEMSP
  2054. m_dwAPIVersion = dwAPIVersion;
  2055. m_AddressState = AS_INSERVICE;
  2056. m_pCallHubTrackingLine = NULL;
  2057. m_dwProviderID = dwProviderID;
  2058. m_pPrivate = NULL;
  2059. m_szAddressName = NULL;
  2060. m_pAddressCaps = NULL;
  2061. m_pDevCaps = NULL;
  2062. //
  2063. // Read the event filter mask from TAPIobject
  2064. //
  2065. SetEventFilterMask( dwEventFilterMask );
  2066. AddRef();
  2067. m_pTAPI->AddRef();
  2068. //
  2069. // default address type
  2070. //
  2071. if (m_dwAPIVersion >= TAPI_VERSION3_0)
  2072. {
  2073. //
  2074. // save msp and address types support
  2075. //
  2076. if ( (pDevCaps->dwDevCapFlags) & LINEDEVCAPFLAGS_MSP )
  2077. {
  2078. m_dwAddressFlags |= ADDRESSFLAG_MSP;
  2079. LOG((TL_INFO, "Initialize - has an msp" ));
  2080. }
  2081. if ( (pDevCaps->dwDevCapFlags) & LINEDEVCAPFLAGS_PRIVATEOBJECTS )
  2082. {
  2083. m_dwAddressFlags |= ADDRESSFLAG_PRIVATEOBJECTS;
  2084. LOG((TL_INFO, "Initialize - has private object" ));
  2085. }
  2086. if ( (pDevCaps->dwDevCapFlags) & LINEDEVCAPFLAGS_CALLHUB )
  2087. {
  2088. m_dwAddressFlags |= ADDRESSFLAG_CALLHUB;
  2089. LOG((TL_INFO, "Initialize - supports callhubs" ));
  2090. }
  2091. if ( (pDevCaps->dwDevCapFlags) & LINEDEVCAPFLAGS_CALLHUBTRACKING )
  2092. {
  2093. m_dwAddressFlags |= ADDRESSFLAG_CALLHUBTRACKING;
  2094. LOG((TL_INFO, "Initialize - supports callhub tracking" ));
  2095. }
  2096. }
  2097. //
  2098. // check for wave device if it doesn't
  2099. // have it's own MSP
  2100. //
  2101. // the sp lets tapi know of wave support through the
  2102. // device classes field, as well
  2103. //
  2104. // so, go through the array
  2105. // and look for the appropriate string
  2106. //
  2107. if ( !(m_dwAddressFlags & ADDRESSFLAG_MSP) && (m_dwAPIVersion >= TAPI_VERSION2_0 ) )
  2108. {
  2109. if (0 != pDevCaps->dwDeviceClassesOffset)
  2110. {
  2111. PWSTR pszDevices;
  2112. //
  2113. // look for full duplex
  2114. // if not full duplex then
  2115. // look for wave out
  2116. // look for wave in
  2117. // if not wave then
  2118. // look for wave
  2119. //
  2120. pszDevices = (PWSTR)( ( (PBYTE)pDevCaps ) + pDevCaps->dwDeviceClassesOffset );
  2121. while (NULL != *pszDevices)
  2122. {
  2123. if (0 == lstrcmpiW(pszDevices, L"wave/in/out"))
  2124. {
  2125. m_dwAddressFlags |= ADDRESSFLAG_WAVEFULLDUPLEX;
  2126. LOG((TL_INFO, "Initialize - supports full duplex wave"));
  2127. break;
  2128. }
  2129. pszDevices += (lstrlenW(pszDevices) + 1 );
  2130. }
  2131. if (!HasWaveDevice())
  2132. {
  2133. pszDevices = (PWSTR)( ( (PBYTE)pDevCaps ) + pDevCaps->dwDeviceClassesOffset );
  2134. //
  2135. // look for wave out
  2136. //
  2137. while (NULL != *pszDevices)
  2138. {
  2139. if (0 == lstrcmpiW(pszDevices, L"wave/out"))
  2140. {
  2141. m_dwAddressFlags |= ADDRESSFLAG_WAVEOUTDEVICE;
  2142. LOG((TL_INFO, "Initialize - supports wave/out device" ));
  2143. break;
  2144. }
  2145. pszDevices += (lstrlenW(pszDevices) +1);
  2146. }
  2147. pszDevices = (PWSTR)( ( (PBYTE)pDevCaps ) + pDevCaps->dwDeviceClassesOffset );
  2148. //
  2149. // look for wave in
  2150. //
  2151. while (NULL != *pszDevices)
  2152. {
  2153. if (0 == lstrcmpiW(pszDevices, L"wave/in"))
  2154. {
  2155. m_dwAddressFlags |= ADDRESSFLAG_WAVEINDEVICE;
  2156. LOG((TL_INFO, "Initialize - supports wave/in device" ));
  2157. break;
  2158. }
  2159. pszDevices += (lstrlenW(pszDevices) +1);
  2160. }
  2161. if (!HasWaveDevice())
  2162. {
  2163. pszDevices = (PWSTR)( ( (PBYTE)pDevCaps ) + pDevCaps->dwDeviceClassesOffset );
  2164. //
  2165. // look for just wave
  2166. // some sps don't differentiate between wave out and wave in
  2167. //
  2168. while (NULL != *pszDevices)
  2169. {
  2170. if (0 == lstrcmpiW(pszDevices, L"wave"))
  2171. {
  2172. m_dwAddressFlags |= (ADDRESSFLAG_WAVEINDEVICE|ADDRESSFLAG_WAVEOUTDEVICE);
  2173. LOG((TL_INFO, "Initialize - supports wave device" ));
  2174. break;
  2175. }
  2176. pszDevices += (lstrlenW(pszDevices) + 1);
  2177. }
  2178. }
  2179. }
  2180. }
  2181. }
  2182. IUnknown * pUnk;
  2183. _InternalQueryInterface(IID_IUnknown, (void**)&pUnk);
  2184. #ifdef USE_PHONEMSP
  2185. if ( HasWaveDevice() || ( NULL != GetHPhoneApp() ) )
  2186. #else
  2187. if ( HasWaveDevice() )
  2188. #endif USE_PHONEMSP
  2189. {
  2190. t3Line.hLine = NULL;
  2191. t3Line.pAddress = this;
  2192. t3Line.dwAddressLineStructHandle = 0;
  2193. hr = LineOpen(
  2194. GetHLineApp(),
  2195. GetDeviceID(),
  2196. GetAddressID(),
  2197. &t3Line,
  2198. GetAPIVersion(),
  2199. LINECALLPRIVILEGE_NONE,
  2200. LINEMEDIAMODE_UNKNOWN,
  2201. 0,
  2202. NULL,
  2203. this,
  2204. GetTapi(),
  2205. FALSE // no need to add to line hash table
  2206. );
  2207. if (S_OK != hr)
  2208. {
  2209. LOG((TL_ERROR, "Initialize failed to open the line"));
  2210. t3Line.hLine = NULL;
  2211. t3Line.dwAddressLineStructHandle = 0;
  2212. }
  2213. //
  2214. // Try to set the event filter mask to the TapiSrv level
  2215. //
  2216. hr = m_EventMasks.SetTapiSrvAddressEventMask(
  2217. t3Line.hLine
  2218. );
  2219. if( FAILED(hr) )
  2220. {
  2221. LOG((TL_ERROR, "SetTapiSrvAddressEventMask failed "));
  2222. }
  2223. m_hLine = t3Line.hLine;
  2224. }
  2225. #ifdef USE_PHONEMSP
  2226. {
  2227. HKEY hKey;
  2228. TCHAR szProviderKeyName[256];
  2229. DWORD dwDataType;
  2230. DWORD dwDataSize = sizeof(DWORD);
  2231. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2232. "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\TAPI3",
  2233. 0,
  2234. KEY_READ,
  2235. &hKey
  2236. ) == ERROR_SUCCESS)
  2237. {
  2238. // form reg name
  2239. wsprintf(szProviderKeyName, ("PreferPhoneMSPForProvider%d"), m_dwProviderID);
  2240. RegQueryValueEx(hKey,
  2241. szProviderKeyName,
  2242. 0,
  2243. &dwDataType,
  2244. (LPBYTE) &bPreferPhoneMSPForProvider,
  2245. &dwDataSize
  2246. );
  2247. RegCloseKey(hKey);
  2248. }
  2249. }
  2250. #endif USE_PHONEMSP
  2251. if ( (m_dwAddressFlags & ADDRESSFLAG_MSP) )
  2252. {
  2253. //
  2254. // CreateMSPObject
  2255. //
  2256. hr = CreateMSPObject(
  2257. m_dwDeviceID,
  2258. pUnk,
  2259. &m_pMSPAggAddress
  2260. );
  2261. if (S_OK != hr)
  2262. {
  2263. LOG((TL_ERROR, "Initialize - CreateMSPObject return %lx", hr));
  2264. m_dwAddressFlags = m_dwAddressFlags & ~(ADDRESSFLAG_MSP);
  2265. }
  2266. }
  2267. else
  2268. {
  2269. #ifdef USE_PHONEMSP
  2270. if(bPreferPhoneMSPForProvider == TRUE)
  2271. {
  2272. // Create the Phone MSP as preference
  2273. //
  2274. if ( NULL != GetHPhoneApp() )
  2275. {
  2276. hr = CreatePhoneDeviceMSP(
  2277. pUnk,
  2278. t3Line.hLine,
  2279. &m_pMSPAggAddress
  2280. );
  2281. if (!SUCCEEDED(hr))
  2282. {
  2283. LOG((TL_ERROR, "Initialize - failed to create phone msp object - %lx", hr));
  2284. }
  2285. }
  2286. //
  2287. // if it's a wave device, create wavemsp object
  2288. //
  2289. else if ( HasWaveDevice() )
  2290. {
  2291. hr = CreateWaveMSPObject(
  2292. pUnk,
  2293. &m_pMSPAggAddress
  2294. );
  2295. if (!SUCCEEDED(hr))
  2296. {
  2297. LOG((TL_ERROR, "Initialize - failed to create wave msp object - %lx", hr));
  2298. m_dwAddressFlags = m_dwAddressFlags & ~(ADDRESSFLAG_WAVEINDEVICE | ADDRESSFLAG_WAVEOUTDEVICE | ADDRESSFLAG_WAVEFULLDUPLEX);
  2299. }
  2300. }
  2301. }
  2302. else
  2303. #endif USE_PHONEMSP
  2304. {
  2305. //
  2306. // if it's a wave device, create wavemsp object as preference
  2307. //
  2308. if ( HasWaveDevice() )
  2309. {
  2310. hr = CreateWaveMSPObject(
  2311. pUnk,
  2312. &m_pMSPAggAddress
  2313. );
  2314. if (!SUCCEEDED(hr))
  2315. {
  2316. LOG((TL_ERROR, "Initialize - failed to create wave msp object - %lx", hr));
  2317. m_dwAddressFlags = m_dwAddressFlags & ~(ADDRESSFLAG_WAVEINDEVICE | ADDRESSFLAG_WAVEOUTDEVICE | ADDRESSFLAG_WAVEFULLDUPLEX);
  2318. }
  2319. }
  2320. #ifdef USE_PHONEMSP
  2321. // Create the Phone MSP
  2322. //
  2323. else if ( NULL != GetHPhoneApp() )
  2324. {
  2325. hr = CreatePhoneDeviceMSP(
  2326. pUnk,
  2327. t3Line.hLine,
  2328. &m_pMSPAggAddress
  2329. );
  2330. if (!SUCCEEDED(hr))
  2331. {
  2332. LOG((TL_ERROR, "Initialize - failed to create phone msp object - %lx", hr));
  2333. }
  2334. }
  2335. #endif USE_PHONEMSP
  2336. }
  2337. }
  2338. pUnk->Release();
  2339. if (NULL != m_pMSPAggAddress)
  2340. {
  2341. m_hMSPEvent = CreateEvent(
  2342. NULL,
  2343. FALSE,
  2344. FALSE,
  2345. NULL
  2346. );
  2347. if ( NULL == m_hMSPEvent )
  2348. {
  2349. LOG((TL_ERROR, "Initialize - can't create MSP event"));
  2350. m_dwAddressFlags = m_dwAddressFlags & ~(ADDRESSFLAG_AMREL);
  2351. //
  2352. // release msp object, so we are not tempted to do Shutdown on it
  2353. // later without having (successfully) initialized it first
  2354. //
  2355. m_pMSPAggAddress->Release();
  2356. m_pMSPAggAddress = NULL;
  2357. }
  2358. else
  2359. {
  2360. // Create a context handle to give the Callback & associate it with this object
  2361. // in the global handle hash table
  2362. m_MSPContext = GenerateHandleAndAddToHashTable((ULONG_PTR)this);
  2363. LOG((TL_INFO, "Initialize - Map MSP handle %p to Address object %p", m_MSPContext, this ));
  2364. BOOL fSuccess = RegisterWaitForSingleObject(
  2365. & m_hWaitEvent,
  2366. m_hMSPEvent,
  2367. MSPEventCallback,
  2368. (PVOID)m_MSPContext,
  2369. INFINITE,
  2370. WT_EXECUTEDEFAULT
  2371. );
  2372. if ( ( ! fSuccess ) || ( NULL == m_hWaitEvent ) )
  2373. {
  2374. LOG((TL_ERROR, "Initialize - RegisterWaitForSingleObject failed"));
  2375. m_dwAddressFlags = m_dwAddressFlags & ~(ADDRESSFLAG_AMREL);
  2376. m_pMSPAggAddress->Release();
  2377. m_pMSPAggAddress = NULL;
  2378. }
  2379. else
  2380. {
  2381. ITMSPAddress * pMSPAddress = GetMSPAddress();
  2382. hr = pMSPAddress->Initialize(
  2383. (MSP_HANDLE)m_hMSPEvent
  2384. );
  2385. if ( SUCCEEDED(hr) && HasWaveDevice() )
  2386. {
  2387. InitializeWaveDeviceIDs( t3Line.hLine );
  2388. }
  2389. pMSPAddress->Release();
  2390. if (!SUCCEEDED(hr))
  2391. {
  2392. LOG((TL_ERROR, "Initialize - failed to initialize msp object - %lx", hr));
  2393. UnregisterWait( m_hWaitEvent );
  2394. m_hWaitEvent = NULL;
  2395. m_dwAddressFlags = m_dwAddressFlags & ~(ADDRESSFLAG_AMREL);
  2396. m_pMSPAggAddress->Release();
  2397. m_pMSPAggAddress = NULL;
  2398. }
  2399. }
  2400. }
  2401. }
  2402. if ( NULL != t3Line.hLine )
  2403. {
  2404. LineClose( &t3Line );
  2405. }
  2406. //
  2407. // get the address caps structure
  2408. //
  2409. hr = UpdateAddressCaps();
  2410. if (S_OK != hr)
  2411. {
  2412. LOG((TL_ERROR, "Initialize - LineGetAddressCaps failed - return %lx", hr ));
  2413. Unlock();
  2414. LOG((TL_ERROR, hr, "Initialize - exit LineGetAddressCaps failed"));
  2415. return hr;
  2416. }
  2417. //
  2418. // save the address name
  2419. //
  2420. if (0 != m_pAddressCaps->dwAddressSize)
  2421. {
  2422. m_szAddress = (PWSTR) ClientAlloc (m_pAddressCaps->dwAddressSize + sizeof(WCHAR));
  2423. if (NULL == m_szAddress)
  2424. {
  2425. LOG((TL_ERROR, "Initialize - alloc m_szAddress failed" ));
  2426. Unlock();
  2427. LOG((TL_ERROR, E_OUTOFMEMORY, "Initialize - exit alloc m_szAddress failed"));
  2428. return E_OUTOFMEMORY;
  2429. }
  2430. memcpy(
  2431. m_szAddress,
  2432. ((LPBYTE)(m_pAddressCaps)) + m_pAddressCaps->dwAddressOffset,
  2433. m_pAddressCaps->dwAddressSize
  2434. );
  2435. LOG((TL_INFO, "CAddress - Address is '%ls'", m_szAddress ));
  2436. }
  2437. hr = SaveAddressName( pDevCaps );
  2438. if ( !SUCCEEDED(hr) )
  2439. {
  2440. LOG((TL_ERROR, "Initialize - SaveAddressName failed %lx", hr));
  2441. ClientFree(m_szAddress);
  2442. /*This is to take care of AV*/
  2443. m_szAddress = NULL;
  2444. Unlock();
  2445. LOG((TL_ERROR, hr, "Initialize - exit SaveAddressName failed"));
  2446. return hr;
  2447. }
  2448. LOG((TL_INFO, "CAddress - m_szAddressName is '%ls'", m_szAddressName ));
  2449. LOG((TL_TRACE, "Initialize - exit S_OK" ));
  2450. Unlock();
  2451. return S_OK;
  2452. }
  2453. #ifdef USE_PHONEMSP
  2454. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2455. //
  2456. // CreatePhoneDeviceMSP
  2457. // This address has a tapi phone devices, so create
  2458. // the relevant terminals
  2459. //
  2460. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2461. HRESULT
  2462. CAddress::CreatePhoneDeviceMSP(
  2463. IUnknown * pUnk,
  2464. HLINE hLine,
  2465. IUnknown ** ppMSPAggAddress
  2466. )
  2467. {
  2468. HRESULT hr = S_OK;
  2469. BOOL bSucceeded = FALSE;
  2470. LPPHONECAPS pPhoneCaps;
  2471. DWORD dwPhoneDevice;
  2472. LPVARSTRING pVarString = NULL;
  2473. CComAggObject<CPhoneMSP> * pPhoneMSP;
  2474. CPhoneMSP * pCPhoneMSP;
  2475. ITMSPAddress * pMSPAddress;
  2476. LOG((TL_TRACE, "CreatePhoneTerminal enter" ));
  2477. //
  2478. // get the related phone device id
  2479. //
  2480. hr = LineGetID(
  2481. hLine,
  2482. GetAddressID(),
  2483. NULL,
  2484. LINECALLSELECT_ADDRESS,
  2485. &pVarString,
  2486. L"tapi/phone"
  2487. );
  2488. //
  2489. // there is no phone device
  2490. //
  2491. if (S_OK != hr)
  2492. {
  2493. if ( NULL != pVarString )
  2494. {
  2495. ClientFree( pVarString );
  2496. /*This is to take care of AV*/
  2497. pVarString = NULL;
  2498. }
  2499. return hr;
  2500. }
  2501. //
  2502. // get the phone device id at the endo
  2503. // of the var string
  2504. //
  2505. if (pVarString->dwStringSize < sizeof(DWORD))
  2506. {
  2507. LOG((TL_ERROR, "CreatePhoneDeviceMSP - dwStringSize < 4" ));
  2508. LOG((TL_ERROR, "CreatePhoneDeviceMSP exit - return LINEERR_OPERATIONFAILED" ));
  2509. ClientFree( pVarString );
  2510. /*This is to take care of AV*/
  2511. pVarString = NULL;
  2512. return mapTAPIErrorCode( LINEERR_OPERATIONFAILED );
  2513. }
  2514. //
  2515. // get the phone device
  2516. //
  2517. dwPhoneDevice = (DWORD) ( * ( ( (PBYTE)pVarString ) + pVarString->dwStringOffset ) );
  2518. ClientFree( pVarString );
  2519. /*This is to take care of AV*/
  2520. pVarString = NULL;
  2521. //
  2522. // create the msp object
  2523. //
  2524. pPhoneMSP = new CComAggObject<CPhoneMSP>(pUnk);
  2525. /*NikhilB: This is to take care of an AV*/
  2526. if ( NULL == pPhoneMSP )
  2527. {
  2528. LOG((TL_ERROR, "Could not allocate for phone MSP object" ));
  2529. return E_OUTOFMEMORY;
  2530. }
  2531. //
  2532. // save the aggregated interface in
  2533. // the msppointer
  2534. //
  2535. pPhoneMSP->QueryInterface(
  2536. IID_IUnknown,
  2537. (void **)ppMSPAggAddress
  2538. );
  2539. //
  2540. // get to the real object
  2541. //
  2542. pMSPAddress = GetMSPAddress();
  2543. pCPhoneMSP = dynamic_cast<CPhoneMSP *>(pMSPAddress);
  2544. //
  2545. // initialize it
  2546. //
  2547. hr = pCPhoneMSP->InitializeTerminals(
  2548. GetHPhoneApp(),
  2549. m_dwAPIVersion,
  2550. dwPhoneDevice,
  2551. this
  2552. );
  2553. pCPhoneMSP->Release();
  2554. if ( !SUCCEEDED(hr) )
  2555. {
  2556. }
  2557. LOG((TL_TRACE, "CreatePhoneDeviceMSP exit - return %lx", hr ));
  2558. return hr;
  2559. }
  2560. #endif USE_PHONEMSP
  2561. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  2562. //
  2563. // AddCall
  2564. // Keep track of calls
  2565. //
  2566. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  2567. HRESULT
  2568. CAddress::AddCall(
  2569. ITCallInfo * pCallInfo
  2570. )
  2571. {
  2572. Lock();
  2573. m_CallArray.Add( pCallInfo );
  2574. Unlock();
  2575. return S_OK;
  2576. }
  2577. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  2578. //
  2579. // RemoveCall
  2580. //
  2581. // remove call from address's list
  2582. //
  2583. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  2584. HRESULT
  2585. CAddress::RemoveCall(
  2586. ITCallInfo * pCallInfo
  2587. )
  2588. {
  2589. Lock();
  2590. m_CallArray.Remove( pCallInfo );
  2591. Unlock();
  2592. return S_OK;
  2593. }
  2594. // ITMediaSupport methods
  2595. HRESULT
  2596. STDMETHODCALLTYPE
  2597. CAddress::get_MediaTypes(
  2598. long * plMediaTypes
  2599. )
  2600. {
  2601. LOG((TL_TRACE, "get_MediaTypes enter" ));
  2602. LOG((TL_TRACE, " plMediaType ------->%p", plMediaTypes ));
  2603. if (TAPIIsBadWritePtr( plMediaTypes, sizeof( long ) ) )
  2604. {
  2605. LOG((TL_ERROR, "get_MediaTypes - bad pointer"));
  2606. return E_POINTER;
  2607. }
  2608. *plMediaTypes = (long)m_dwMediaModesSupported;
  2609. if (*plMediaTypes & LINEMEDIAMODE_INTERACTIVEVOICE)
  2610. {
  2611. *plMediaTypes |= LINEMEDIAMODE_AUTOMATEDVOICE;
  2612. }
  2613. *plMediaTypes &= ALLMEDIAMODES;
  2614. return S_OK;
  2615. }
  2616. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  2617. //
  2618. // QueryMediaType
  2619. // find out of mediatype is supported
  2620. //
  2621. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  2622. HRESULT
  2623. STDMETHODCALLTYPE
  2624. CAddress::QueryMediaType(
  2625. long lMediaType,
  2626. VARIANT_BOOL * pbSupport
  2627. )
  2628. {
  2629. HRESULT hr = S_OK;
  2630. DWORD dwMediaMode;
  2631. LOG((TL_TRACE, "QueryMediaType enter"));
  2632. LOG((TL_TRACE, " lMediaType--------->%lx", lMediaType));
  2633. LOG((TL_TRACE, " pbSupport---------->%p", pbSupport));
  2634. if ( TAPIIsBadWritePtr( pbSupport, sizeof(VARIANT_BOOL) ) )
  2635. {
  2636. LOG((TL_ERROR, "QueryMediaType - inval pointer"));
  2637. return E_POINTER;
  2638. }
  2639. //
  2640. // get the tapi mediamode that
  2641. // the application is asking about
  2642. //
  2643. if (GetMediaMode(
  2644. lMediaType,
  2645. &dwMediaMode
  2646. ) )
  2647. {
  2648. *pbSupport = VARIANT_TRUE;
  2649. }
  2650. else
  2651. {
  2652. *pbSupport = VARIANT_FALSE;
  2653. }
  2654. LOG((TL_TRACE, "QueryMediaType exit - return success"));
  2655. return S_OK;
  2656. }
  2657. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2658. //
  2659. // AddCallNotification
  2660. //
  2661. // Adds a callback to notify on call events
  2662. //
  2663. // dwPrivs
  2664. // IN tapi 2 style Privileges
  2665. //
  2666. // dwMediaModes
  2667. // IN tapi 2 style mediamodes
  2668. //
  2669. // pNotification
  2670. // IN the callback to notify
  2671. //
  2672. // pulRegiser
  2673. // OUT the unique ID of the callback (so they can unregister)
  2674. //
  2675. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2676. HRESULT
  2677. CAddress::AddCallNotification(
  2678. DWORD dwPrivs,
  2679. DWORD dwMediaModes,
  2680. long lInstance,
  2681. PVOID * ppRegister
  2682. )
  2683. {
  2684. HRESULT hr;
  2685. AddressLineStruct * pAddressLine;
  2686. //
  2687. // create addressline
  2688. //
  2689. pAddressLine = (AddressLineStruct *)ClientAlloc( sizeof( AddressLineStruct ) );
  2690. if (NULL == pAddressLine)
  2691. {
  2692. LOG((TL_ERROR, "AddCallNotification - pAddressLine is NULL"));
  2693. return E_OUTOFMEMORY;
  2694. }
  2695. //
  2696. // initialize
  2697. //
  2698. pAddressLine->dwPrivs = dwPrivs;
  2699. pAddressLine->t3Line.pAddress = this;
  2700. pAddressLine->t3Line.dwAddressLineStructHandle = 0;
  2701. pAddressLine->InitializeRefcount(1);
  2702. pAddressLine->lCallbackInstance = lInstance;
  2703. if (ALLMEDIATYPES == dwMediaModes)
  2704. {
  2705. pAddressLine->dwMediaModes = GetMediaModes();
  2706. }
  2707. else
  2708. {
  2709. pAddressLine->dwMediaModes = dwMediaModes;
  2710. //
  2711. // if we are listening on any audio mode
  2712. //
  2713. if (pAddressLine->dwMediaModes & AUDIOMEDIAMODES)
  2714. {
  2715. //
  2716. // add in all the audio modes that we support
  2717. //
  2718. pAddressLine->dwMediaModes |= (GetMediaModes() & AUDIOMEDIAMODES);
  2719. }
  2720. }
  2721. //
  2722. // get a line
  2723. //
  2724. hr = LineOpen(
  2725. GetHLineApp(),
  2726. GetDeviceID(),
  2727. GetAddressID(),
  2728. &(pAddressLine->t3Line),
  2729. GetAPIVersion(),
  2730. pAddressLine->dwPrivs,
  2731. pAddressLine->dwMediaModes,
  2732. pAddressLine,
  2733. NULL,
  2734. (CAddress *)this,
  2735. GetTapi()
  2736. );
  2737. if (!SUCCEEDED(hr))
  2738. {
  2739. LOG((TL_ERROR, "AddCallNotification - LineOpen failed %lx", hr));
  2740. ClientFree( pAddressLine );
  2741. return hr;
  2742. }
  2743. //
  2744. // Try to set the event filter mask to the TapiSrv level
  2745. //
  2746. hr = m_EventMasks.SetTapiSrvAddressEventMask(
  2747. pAddressLine->t3Line.hLine
  2748. );
  2749. if( FAILED(hr) )
  2750. {
  2751. LOG((TL_ERROR, "AddCallNotification - SetTapiSrvAddressEventMask failed 0x%08x", hr));
  2752. LineClose( &(pAddressLine->t3Line) );
  2753. ClientFree( pAddressLine );
  2754. return hr;
  2755. }
  2756. // Fix for bug 263866 & 250924
  2757. //
  2758. if ( m_dwAddressFlags & ADDRESSFLAG_MSP )
  2759. {
  2760. hr = LineCreateMSPInstance(
  2761. pAddressLine->t3Line.hLine,
  2762. GetAddressID()
  2763. );
  2764. if ( !SUCCEEDED(hr) )
  2765. {
  2766. LOG((TL_ERROR, "AddCallNotification - LineCreateMSPInstance failed %lx", hr));
  2767. LineClose( &(pAddressLine->t3Line) );
  2768. ClientFree( pAddressLine );
  2769. return hr;
  2770. }
  2771. }
  2772. // Tell TAPISRV what status messages we want
  2773. // NOTE : if the lines SP doesn't support TSPI_lineSetStatusMessages
  2774. // TAPISRV will fail this with LINEERR_OPERATIONUNAVAIL
  2775. LineSetStatusMessages(
  2776. &(pAddressLine->t3Line),
  2777. ALL_LINEDEVSTATE_MESSAGES,
  2778. ALL_LINEADDRESSSTATE_MESSAGES
  2779. );
  2780. //
  2781. // ZoltanS fix: enable callhub notifications only if the app
  2782. // hasn't already told us it doesn't want them
  2783. //
  2784. if ( m_fEnableCallHubTrackingOnLineOpen )
  2785. {
  2786. LINECALLHUBTRACKINGINFO lchti;
  2787. lchti.dwTotalSize = sizeof(lchti);
  2788. lchti.dwCurrentTracking = LINECALLHUBTRACKING_ALLCALLS;
  2789. hr = LineSetCallHubTracking(
  2790. &(pAddressLine->t3Line),
  2791. &lchti
  2792. );
  2793. if ( S_OK != hr )
  2794. {
  2795. LOG((TL_ERROR, "AddCallNotification - LineSetCallHubTracking failed %lx", hr ));
  2796. LineClose( &(pAddressLine->t3Line) );
  2797. ClientFree( pAddressLine );
  2798. return hr;
  2799. }
  2800. }
  2801. if (m_pCallHubTrackingLine)
  2802. {
  2803. MaybeCloseALine( &m_pCallHubTrackingLine );
  2804. m_pCallHubTrackingLine = pAddressLine;
  2805. pAddressLine->AddRef();
  2806. }
  2807. //
  2808. // save the line in the address's list
  2809. //
  2810. hr = AddNotificationLine( pAddressLine );;
  2811. if ( S_OK != hr )
  2812. {
  2813. LOG((TL_ERROR, "AddCallNotification - AddNotificationLine failed %lx", hr ));
  2814. LineClose( &(pAddressLine->t3Line) );
  2815. ClientFree( pAddressLine );
  2816. }
  2817. else
  2818. {
  2819. //
  2820. // fill in pulRegister
  2821. //
  2822. *ppRegister = (PVOID) pAddressLine;
  2823. }
  2824. return hr;
  2825. }
  2826. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2827. //
  2828. // RemoveCallNotification
  2829. //
  2830. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2831. HRESULT
  2832. CAddress::RemoveCallNotification(
  2833. PVOID pRegister
  2834. )
  2835. {
  2836. AddressLineStruct *pLine = (AddressLineStruct *)pRegister;
  2837. MaybeCloseALine( &pLine );
  2838. return S_OK;
  2839. }
  2840. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2841. //
  2842. // FindOrOpenALine
  2843. //
  2844. // Attempts to find a line that's already open. If so, keeps a
  2845. // pointer to it. If not opens the line.
  2846. //
  2847. // dwMediaModes
  2848. // IN tapi 2 style mediamodes
  2849. //
  2850. // ppAddressLine
  2851. // OUT addresslinestruct associated with this request
  2852. //
  2853. // RETURNS
  2854. //
  2855. //
  2856. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2857. HRESULT
  2858. CAddress::FindOrOpenALine(
  2859. DWORD dwMediaModes,
  2860. AddressLineStruct ** ppAddressLine
  2861. )
  2862. {
  2863. HRESULT hr = S_OK;
  2864. LOG((TL_TRACE, "FindOrOpenALine - enter" ));
  2865. Lock();
  2866. //
  2867. // if there is already a line,
  2868. // just return it
  2869. //
  2870. if ( m_AddressLinesPtrList.size() > 0 )
  2871. {
  2872. LOG((TL_INFO, "Found a line that is already open" ));
  2873. *ppAddressLine = (AddressLineStruct *)*( m_AddressLinesPtrList.begin() );
  2874. (*ppAddressLine)->AddRef();
  2875. LOG((TL_TRACE, "FindOrOpenALine - exit"));
  2876. Unlock();
  2877. return S_OK;
  2878. }
  2879. //
  2880. // we didn't have an address
  2881. //
  2882. LOG((TL_INFO, "Did not find an already open line"));
  2883. //
  2884. // create a new addressline
  2885. //
  2886. AddressLineStruct * pLine = (AddressLineStruct *)ClientAlloc( sizeof(AddressLineStruct) );
  2887. if (NULL == pLine)
  2888. {
  2889. LOG((TL_ERROR, "FindOrOpenALine - alloc pLine failed" ));
  2890. Unlock();
  2891. return E_OUTOFMEMORY;
  2892. }
  2893. //
  2894. // initialize
  2895. //
  2896. pLine->dwMediaModes = dwMediaModes;
  2897. pLine->dwPrivs = LINECALLPRIVILEGE_NONE;
  2898. pLine->t3Line.pAddress = this;
  2899. pLine->t3Line.dwAddressLineStructHandle = 0;
  2900. pLine->InitializeRefcount(1);
  2901. pLine->lCallbackInstance = 0;
  2902. LOG((TL_INFO, "FindOrOpenALine - Opening a line" ));
  2903. //
  2904. // open the line
  2905. //
  2906. hr = LineOpen(
  2907. GetHLineApp(),
  2908. GetDeviceID(),
  2909. GetAddressID(),
  2910. &(pLine->t3Line),
  2911. GetAPIVersion(),
  2912. LINECALLPRIVILEGE_NONE,
  2913. dwMediaModes,
  2914. pLine,
  2915. NULL,
  2916. this,
  2917. GetTapi()
  2918. );
  2919. if (S_OK != hr)
  2920. {
  2921. LOG((TL_ERROR, "FindOrOpenALine - LineOpen failed %lx", hr ));
  2922. ClientFree( pLine );
  2923. Unlock();
  2924. return hr;
  2925. }
  2926. //
  2927. // Try to set the event filter mask to the TapiSrv level
  2928. //
  2929. hr = m_EventMasks.SetTapiSrvAddressEventMask(
  2930. pLine->t3Line.hLine
  2931. );
  2932. if( FAILED(hr) )
  2933. {
  2934. LOG((TL_ERROR, "FindOrOpenALine - SetTapiSrvAddressEventMask failed 0x%08x", hr));
  2935. LineClose( &(pLine->t3Line) );
  2936. ClientFree( pLine );
  2937. Unlock();
  2938. return hr;
  2939. }
  2940. if ( m_dwAddressFlags & ADDRESSFLAG_MSP )
  2941. {
  2942. hr = LineCreateMSPInstance(
  2943. pLine->t3Line.hLine,
  2944. GetAddressID()
  2945. );
  2946. if ( !SUCCEEDED(hr) )
  2947. {
  2948. LOG((TL_ERROR, "FindOrOpenALine - LineCreateMSPInstance failed %lx", hr));
  2949. LineClose( &(pLine->t3Line) );
  2950. ClientFree( pLine );
  2951. Unlock();
  2952. return hr;
  2953. }
  2954. }
  2955. // Tell TAPISRV what status messages we want
  2956. // NOTE : if the lines SP doesn't support TSPI_lineSetStatusMessages
  2957. // TAPISRV will fail this with LINEERR_OPERATIONUNAVAIL
  2958. LineSetStatusMessages(
  2959. &(pLine->t3Line),
  2960. ALL_LINEDEVSTATE_MESSAGES,
  2961. ALL_LINEADDRESSSTATE_MESSAGES
  2962. );
  2963. //
  2964. // ZoltanS fix: enable callhub notifications only if the app
  2965. // hasn't already told us it doesn't want them
  2966. //
  2967. if ( m_fEnableCallHubTrackingOnLineOpen )
  2968. {
  2969. LINECALLHUBTRACKINGINFO lchti;
  2970. lchti.dwTotalSize = sizeof(lchti);
  2971. lchti.dwCurrentTracking = LINECALLHUBTRACKING_ALLCALLS;
  2972. hr = LineSetCallHubTracking(
  2973. &(pLine->t3Line),
  2974. &lchti
  2975. );
  2976. if ( S_OK != hr )
  2977. {
  2978. LOG((TL_ERROR, "FindOrOpenALine - LineSetCallHubTracking failed %lx", hr ));
  2979. LineClose( &(pLine->t3Line) );
  2980. ClientFree( pLine );
  2981. Unlock();
  2982. return hr;
  2983. }
  2984. }
  2985. //
  2986. // Add this line to our list of open lines. This is independent of
  2987. // the callhub tracking stuff above.
  2988. //
  2989. hr = AddNotificationLine( pLine );
  2990. if ( S_OK != hr )
  2991. {
  2992. LOG((TL_ERROR, "FindOrOpenALine - AddNotificationLine failed %lx", hr ));
  2993. LineClose( &(pLine->t3Line) );
  2994. ClientFree( pLine );
  2995. }
  2996. else
  2997. {
  2998. *ppAddressLine = pLine;
  2999. }
  3000. LOG((TL_TRACE, "FindOrOpenALine - exit"));
  3001. Unlock();
  3002. return hr;
  3003. }
  3004. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3005. //
  3006. // MaybeCloseALine
  3007. // After a call is done, close the line if it's not being
  3008. // used for monitoring.
  3009. //
  3010. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3011. HRESULT
  3012. CAddress::MaybeCloseALine(
  3013. AddressLineStruct ** ppAddressLine
  3014. )
  3015. {
  3016. HRESULT hr = S_OK;
  3017. LOG((TL_TRACE, "MaybeCloseALine - enter"));
  3018. Lock();
  3019. if (NULL == *ppAddressLine || !IsValidAddressLine(*ppAddressLine))
  3020. {
  3021. Unlock();
  3022. return S_OK;
  3023. }
  3024. //
  3025. // decrement reference count on the the address line
  3026. //
  3027. DWORD dwAddressLineRefcount = (*ppAddressLine)->Release();
  3028. //
  3029. // if ref count is 0, close line
  3030. //
  3031. if ( 0 == dwAddressLineRefcount )
  3032. {
  3033. m_AddressLinesPtrList.remove( (PVOID)*ppAddressLine );
  3034. //
  3035. // clean handle table.
  3036. //
  3037. try
  3038. {
  3039. DWORD dwAddressLineHandle = (*ppAddressLine)->t3Line.dwAddressLineStructHandle;
  3040. DeleteHandleTableEntry(dwAddressLineHandle);
  3041. }
  3042. catch(...)
  3043. {
  3044. LOG((TL_ERROR,
  3045. "MaybeCloseALine - exception accessing address line's handle" ));
  3046. _ASSERTE(FALSE);
  3047. }
  3048. //
  3049. // attempt to close the line
  3050. //
  3051. LOG((TL_INFO, "MaybeCloseALine - Calling LineClose" ));
  3052. if ( m_dwAddressFlags & ADDRESSFLAG_MSP )
  3053. {
  3054. LineCloseMSPInstance( (*ppAddressLine)->t3Line.hLine );
  3055. }
  3056. //
  3057. // release the lock and call lineclose
  3058. //
  3059. Unlock();
  3060. //
  3061. // now that the line was removed from our list of managed lines and all
  3062. // the calls have been notified, we can close the line and free the
  3063. // structure
  3064. //
  3065. hr = LineClose(
  3066. &((*ppAddressLine)->t3Line)
  3067. );
  3068. ClientFree( *ppAddressLine );
  3069. }
  3070. else
  3071. {
  3072. Unlock();
  3073. //
  3074. // otherwise, decrement the dwRefCount count
  3075. //
  3076. LOG((TL_INFO, "MaybeCloseALine - Not calling line close - decrementing number of addresses using line" ));
  3077. }
  3078. *ppAddressLine = NULL;
  3079. LOG((TL_TRACE, "MaybeCloseALine - exit"));
  3080. return hr;
  3081. }
  3082. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3083. //
  3084. // SetCallHubTracking
  3085. //
  3086. // called by the tapi object to start callhub tracking on this
  3087. // address
  3088. //
  3089. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3090. HRESULT
  3091. CAddress::SetCallHubTracking(
  3092. BOOL bSet
  3093. )
  3094. {
  3095. HRESULT hr = S_OK;
  3096. LINECALLHUBTRACKINGINFO lchti;
  3097. Lock();
  3098. //
  3099. // Check if we have to make any change now.
  3100. //
  3101. if ( bSet == m_fEnableCallHubTrackingOnLineOpen )
  3102. {
  3103. //
  3104. // already doing the right thing
  3105. //
  3106. Unlock();
  3107. return S_OK;
  3108. }
  3109. //
  3110. // ZoltanS: make sure we don't clobber this setting in other methods
  3111. // (e.g., AddCallNotification or FindOrOpenALine) where the
  3112. // default call notification behavior (true) would otherwise
  3113. // be set.
  3114. //
  3115. m_fEnableCallHubTrackingOnLineOpen = bSet;
  3116. //
  3117. // need an hline to call setcallhubtracking
  3118. //
  3119. if ( m_pCallHubTrackingLine == NULL )
  3120. {
  3121. hr = FindOrOpenALine(
  3122. LINEMEDIAMODE_INTERACTIVEVOICE,
  3123. &m_pCallHubTrackingLine
  3124. );
  3125. if ( !SUCCEEDED( hr ) )
  3126. {
  3127. LOG((TL_ERROR, "SCHT - FindOrOpen failed %lx", hr));
  3128. Unlock();
  3129. return hr;
  3130. }
  3131. //
  3132. // ZoltanS fix:
  3133. // FindOrOpenALine does callhubtracking for non-sp
  3134. // tracking capable lines, but only if it is opening
  3135. // the line (rather than just finding it in our list.
  3136. // So we still need to do LineSetCallHubTracking below,
  3137. // even for an SPCallHubTrackingAddress.
  3138. //
  3139. }
  3140. //
  3141. // tell the sp to track callhubs
  3142. //
  3143. ZeroMemory(
  3144. &lchti,
  3145. sizeof(lchti)
  3146. );
  3147. lchti.dwTotalSize = sizeof(lchti);
  3148. lchti.dwCurrentTracking = bSet? LINECALLHUBTRACKING_ALLCALLS :
  3149. LINECALLHUBTRACKING_NONE;
  3150. //
  3151. // ZoltanS: Only pass this flag if it applies.
  3152. // Note: LineSetCallHubTracking apparently ignores its first argument
  3153. // if the tracking level is set to LINECALLHUBTRACKING_NONE; otherwise
  3154. // we would also have to FindOrOpenALine if we are unsetting.
  3155. //
  3156. if ( bSet && IsSPCallHubTrackingAddress() )
  3157. {
  3158. lchti.dwCurrentTracking |= LINECALLHUBTRACKING_PROVIDERLEVEL;
  3159. }
  3160. hr = LineSetCallHubTracking(
  3161. &(m_pCallHubTrackingLine->t3Line),
  3162. &lchti
  3163. );
  3164. if ( !SUCCEEDED( hr ) )
  3165. {
  3166. LOG((TL_ERROR, "SCHT - LSCHT failed %lx", hr));
  3167. if ( bSet )
  3168. {
  3169. MaybeCloseALine( &m_pCallHubTrackingLine );
  3170. m_pCallHubTrackingLine = NULL;
  3171. }
  3172. Unlock();
  3173. return hr;
  3174. }
  3175. //
  3176. // Also properly set callhub tracking on lines that were
  3177. // opened for call notification
  3178. //
  3179. PtrList::iterator l;
  3180. for (l = m_AddressLinesPtrList.begin(); l != m_AddressLinesPtrList.end(); l++)
  3181. {
  3182. AddressLineStruct * pLine;
  3183. pLine = (AddressLineStruct *)(*l);
  3184. if (pLine != m_pCallHubTrackingLine)
  3185. {
  3186. LineSetCallHubTracking(
  3187. &(pLine->t3Line),
  3188. &lchti
  3189. );
  3190. }
  3191. }
  3192. //
  3193. // close it if unsetting
  3194. //
  3195. if ( !bSet )
  3196. {
  3197. MaybeCloseALine( &m_pCallHubTrackingLine );
  3198. m_pCallHubTrackingLine = NULL;
  3199. }
  3200. Unlock();
  3201. return S_OK;
  3202. }
  3203. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3204. //
  3205. // DoesThisAddressSupportCallHubs
  3206. //
  3207. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3208. DWORD
  3209. CAddress::DoesThisAddressSupportCallHubs(
  3210. CCall * pCall
  3211. )
  3212. {
  3213. HCALL hCall;
  3214. LINECALLINFO * pCallInfo;
  3215. HRESULT hr;
  3216. //
  3217. // does the sp tell us it supports callhubs?
  3218. //
  3219. if ( IsSPCallHubAddress() )
  3220. {
  3221. return CALLHUBSUPPORT_FULL;
  3222. }
  3223. //
  3224. // have we already determined that it doesn't?
  3225. //
  3226. if ( m_dwAddressFlags & ADDRESSFLAG_NOCALLHUB )
  3227. {
  3228. return CALLHUBSUPPORT_NONE;
  3229. }
  3230. //
  3231. // otherwise - hack - see if the dwrelatedcallid
  3232. // field is non-zero in this call.
  3233. // if so, it does callhubs,
  3234. //
  3235. hCall = pCall->GetHCall();
  3236. hr = LineGetCallInfo(
  3237. hCall,
  3238. &pCallInfo
  3239. );
  3240. if ( SUCCEEDED( hr ) )
  3241. {
  3242. if ( 0 != pCallInfo->dwCallID )
  3243. {
  3244. Lock();
  3245. m_dwAddressFlags |= ADDRESSFLAG_CALLHUB;
  3246. Unlock();
  3247. ClientFree( pCallInfo );
  3248. return CALLHUBSUPPORT_FULL;
  3249. }
  3250. else
  3251. {
  3252. Lock();
  3253. m_dwAddressFlags |= ADDRESSFLAG_NOCALLHUB;
  3254. Unlock();
  3255. ClientFree( pCallInfo );
  3256. return CALLHUBSUPPORT_NONE;
  3257. }
  3258. }
  3259. return CALLHUBSUPPORT_UNKNOWN;
  3260. }
  3261. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3262. //
  3263. // CreateForwardInfoObject
  3264. //
  3265. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3266. STDMETHODIMP
  3267. CAddress::CreateForwardInfoObject(
  3268. ITForwardInformation ** ppForwardInfo
  3269. )
  3270. {
  3271. CComObject< CForwardInfo > * p;
  3272. HRESULT hr = S_OK;
  3273. LOG((TL_TRACE, "CreatForwardInfoObject - enter"));
  3274. if (TAPIIsBadWritePtr(ppForwardInfo , sizeof(ITForwardInformation *) ) )
  3275. {
  3276. LOG((TL_ERROR, "CreateForwardInfoObject - bad pointer"));
  3277. return E_POINTER;
  3278. }
  3279. //
  3280. // create object
  3281. //
  3282. CComObject< CForwardInfo >::CreateInstance( &p );
  3283. if ( NULL == p )
  3284. {
  3285. LOG((TL_ERROR, "Create forward object failed"));
  3286. return E_OUTOFMEMORY;
  3287. }
  3288. //
  3289. // init
  3290. //
  3291. hr = p->Initialize();
  3292. if ( !SUCCEEDED(hr) )
  3293. {
  3294. LOG((TL_ERROR, "Initialize forward object failed"));
  3295. delete p;
  3296. return hr;
  3297. }
  3298. //
  3299. // return
  3300. //
  3301. hr = p->QueryInterface(
  3302. IID_ITForwardInformation,
  3303. (void**)ppForwardInfo
  3304. );
  3305. if ( !SUCCEEDED(hr) )
  3306. {
  3307. LOG((TL_ERROR, "CreateForwardobject failed - %lx", hr));
  3308. delete p;
  3309. return hr;
  3310. }
  3311. LOG((TL_TRACE, "CreateForwardObject - exit success"));
  3312. return S_OK;
  3313. }
  3314. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3315. //
  3316. // Forward - simple forwarding
  3317. //
  3318. // will unconditially forward to pDestAddress
  3319. //
  3320. // if pDestAddress is NULL, will cancel forwarding
  3321. //
  3322. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3323. STDMETHODIMP
  3324. CAddress::Forward(
  3325. ITForwardInformation * pForwardInfo,
  3326. ITBasicCallControl * pCall
  3327. )
  3328. {
  3329. HRESULT hr;
  3330. LINEFORWARDLIST * pList;
  3331. AddressLineStruct * pLine;
  3332. HCALL hCall = NULL;
  3333. CForwardInfo * pFI;
  3334. CCall * pCCall;
  3335. LONG lCap;
  3336. if ( IsBadReadPtr( pForwardInfo, sizeof( ITForwardInformation * ) ) )
  3337. {
  3338. LOG((TL_ERROR, "Forward - bad pForwardInfo"));
  3339. return E_POINTER;
  3340. }
  3341. hr = get_AddressCapability( AC_ADDRESSCAPFLAGS, &lCap );
  3342. if ( !SUCCEEDED(hr) )
  3343. {
  3344. return hr;
  3345. }
  3346. if ( lCap & LINEADDRCAPFLAGS_FWDCONSULT )
  3347. {
  3348. if ( IsBadReadPtr( pCall, sizeof(ITBasicCallControl *) ) )
  3349. {
  3350. LOG((TL_ERROR, "Forward - Need consultation call"));
  3351. return E_INVALIDARG;
  3352. }
  3353. pCCall = dynamic_cast<CCall *>(pCall);
  3354. if ( NULL == pCCall )
  3355. {
  3356. LOG((TL_ERROR, "Forward - invalid call"));
  3357. return E_POINTER;
  3358. }
  3359. }
  3360. pFI = dynamic_cast<CForwardInfo *>(pForwardInfo);
  3361. if ( NULL == pFI )
  3362. {
  3363. return E_POINTER;
  3364. }
  3365. hr = pFI->CreateForwardList( &pList );
  3366. if ( !SUCCEEDED(hr) )
  3367. {
  3368. return hr;
  3369. }
  3370. //
  3371. // get a line
  3372. //
  3373. hr = FindOrOpenALine(
  3374. LINEMEDIAMODE_INTERACTIVEVOICE,
  3375. &pLine
  3376. );
  3377. if ( !SUCCEEDED(hr) )
  3378. {
  3379. LOG((TL_ERROR, "Forward - FindOrOpen failed - %lx", hr));
  3380. ClientFree( pList );
  3381. return hr;
  3382. }
  3383. //
  3384. // call forward
  3385. //
  3386. //
  3387. DWORD dwRings;
  3388. pForwardInfo->get_NumRingsNoAnswer( (long *)&dwRings );
  3389. hr = LineForward(
  3390. &(pLine->t3Line),
  3391. m_dwAddressID,
  3392. pList,
  3393. dwRings,
  3394. &hCall
  3395. );
  3396. ClientFree( pList );
  3397. if ( ((long)hr) < 0 )
  3398. {
  3399. LOG((TL_ERROR, "Forward failed sync - %lx", hr));
  3400. MaybeCloseALine( &pLine );
  3401. return hr;
  3402. }
  3403. hr = WaitForReply( hr );
  3404. if ( lCap & LINEADDRCAPFLAGS_FWDCONSULT )
  3405. {
  3406. pCCall->Lock();
  3407. pCCall->FinishSettingUpCall( hCall );
  3408. pCCall->Unlock();
  3409. }
  3410. else
  3411. {
  3412. HRESULT hr2;
  3413. if( hCall != NULL )
  3414. {
  3415. hr2 = LineDrop(
  3416. hCall,
  3417. NULL,
  3418. 0
  3419. );
  3420. if ( ((long)hr2) > 0 )
  3421. {
  3422. hr2 = WaitForReply( hr2 );
  3423. }
  3424. LineDeallocateCall( hCall );
  3425. }
  3426. }
  3427. MaybeCloseALine( &pLine );
  3428. if ( !SUCCEEDED(hr) )
  3429. {
  3430. LOG((TL_ERROR, "Forward failed async - %lx", hr));
  3431. return hr;
  3432. }
  3433. LOG((TL_TRACE, "Forward - Exit"));
  3434. return S_OK;
  3435. }
  3436. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3437. // Class : CAddress
  3438. // Interface : ITAddress
  3439. // Method : get_CurrentForwardInfo
  3440. //
  3441. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3442. STDMETHODIMP
  3443. CAddress::get_CurrentForwardInfo(
  3444. ITForwardInformation ** ppForwardInfo
  3445. )
  3446. {
  3447. HRESULT hr = S_OK;
  3448. AddressLineStruct * pLine = NULL;
  3449. LINEADDRESSSTATUS * pAddressStatus = NULL;
  3450. LINEFORWARD * plineForward = NULL;
  3451. DWORD dwNumEntries = 0;
  3452. DWORD dwCount = 0;
  3453. PWSTR pszCallerAddress = NULL;
  3454. PWSTR pszDestddress = NULL;
  3455. LOG((TL_TRACE, "get_CurrentForwardInfo - enter"));
  3456. hr = CreateForwardInfoObject(ppForwardInfo);
  3457. if ( SUCCEEDED(hr) )
  3458. {
  3459. hr = FindOrOpenALine(
  3460. LINEMEDIAMODE_INTERACTIVEVOICE,
  3461. &pLine
  3462. );
  3463. if ( SUCCEEDED(hr) )
  3464. {
  3465. hr = LineGetAddressStatus(
  3466. &(pLine->t3Line),
  3467. m_dwAddressID,
  3468. &pAddressStatus
  3469. );
  3470. if ( SUCCEEDED(hr) )
  3471. {
  3472. (*ppForwardInfo)->put_NumRingsNoAnswer(pAddressStatus->dwNumRingsNoAnswer);
  3473. //
  3474. // if there is forwarding
  3475. //
  3476. dwNumEntries = pAddressStatus->dwForwardNumEntries;
  3477. plineForward = (LINEFORWARD *) (((LPBYTE)pAddressStatus) + pAddressStatus->dwForwardOffset);
  3478. for (dwCount = 0; dwCount != dwNumEntries; dwCount++)
  3479. {
  3480. if (plineForward->dwCallerAddressOffset > 0) // Caller address is not used for some forward modes
  3481. {
  3482. pszCallerAddress = (PWSTR) (((LPBYTE)pAddressStatus) + plineForward->dwCallerAddressOffset);
  3483. }
  3484. pszDestddress = (PWSTR) (((LPBYTE)pAddressStatus) + plineForward->dwDestAddressOffset);
  3485. if ( m_dwAPIVersion >= TAPI_VERSION3_1 )
  3486. {
  3487. //
  3488. // We have negotiated TAPI3.1 or better, so we can get the address types.
  3489. //
  3490. ITForwardInformation2 * pForwardInfo2;
  3491. //
  3492. // Get the ITForwardInformation2 interface so we can call SetForwardType2
  3493. //
  3494. hr = (*ppForwardInfo)->QueryInterface(
  3495. IID_ITForwardInformation2,
  3496. (void **)&pForwardInfo2
  3497. );
  3498. if ( SUCCEEDED(hr) )
  3499. {
  3500. pForwardInfo2->SetForwardType2(plineForward->dwForwardMode,
  3501. pszDestddress,
  3502. plineForward->dwDestAddressType,
  3503. pszCallerAddress,
  3504. plineForward->dwCallerAddressType
  3505. );
  3506. pForwardInfo2->Release();
  3507. }
  3508. else
  3509. {
  3510. LOG((TL_ERROR, "get_CurrentForwardInfo - QueryInterface failed - %lx", hr));
  3511. //
  3512. // If for some reason the QI fails, break out of the loop
  3513. //
  3514. break;
  3515. }
  3516. }
  3517. else
  3518. {
  3519. (*ppForwardInfo)->SetForwardType(plineForward->dwForwardMode,
  3520. pszDestddress,
  3521. pszCallerAddress
  3522. );
  3523. }
  3524. plineForward++;
  3525. }
  3526. ClientFree( pAddressStatus );
  3527. }
  3528. else
  3529. {
  3530. LOG((TL_ERROR, "get_CurrentForwardInfo - LineGetAddressStatus failed "));
  3531. }
  3532. MaybeCloseALine( &pLine );
  3533. }
  3534. else
  3535. {
  3536. LOG((TL_ERROR, "get_CurrentForwardInfo - FindOrOpen failed"));
  3537. }
  3538. }
  3539. else
  3540. {
  3541. LOG((TL_ERROR, "get_CurrentForwardInfo - failed to create"));
  3542. }
  3543. LOG((TL_TRACE, hr, "get_CurrentForwardInfo - exit"));
  3544. return hr;
  3545. }
  3546. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3547. //
  3548. //
  3549. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3550. STDMETHODIMP
  3551. CAddress::get_DialableAddress(
  3552. BSTR * ppDialableAddress
  3553. )
  3554. {
  3555. HRESULT hr = S_OK;
  3556. LOG((TL_TRACE, "get_DialableAddress - Enter"));
  3557. if (TAPIIsBadWritePtr(ppDialableAddress , sizeof(BSTR) ) )
  3558. {
  3559. LOG((TL_ERROR, "get_DialableAddress - bad pointer"));
  3560. return E_POINTER;
  3561. }
  3562. *ppDialableAddress = SysAllocString( m_szAddress );
  3563. if ( ( NULL == *ppDialableAddress ) && ( NULL != m_szAddress ) )
  3564. {
  3565. LOG((TL_TRACE, "SysAllocString Failed" ));
  3566. hr = E_OUTOFMEMORY;
  3567. }
  3568. LOG((TL_TRACE, "get_DialableAddress - Exit"));
  3569. return hr;
  3570. }
  3571. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3572. //
  3573. //
  3574. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3575. STDMETHODIMP
  3576. CAddress::put_MessageWaiting(
  3577. VARIANT_BOOL fMessageWaiting
  3578. )
  3579. {
  3580. HRESULT hr = S_OK;
  3581. AddressLineStruct * pLine = NULL;
  3582. LOG((TL_TRACE, "put_MessageWaiting - Enter"));
  3583. hr = FindOrOpenALine(
  3584. LINEMEDIAMODE_INTERACTIVEVOICE,
  3585. &pLine
  3586. );
  3587. if ( !SUCCEEDED(hr) )
  3588. {
  3589. LOG((TL_ERROR, "put_MessageWaiting - findoropen failed %lx", hr));
  3590. return hr;
  3591. }
  3592. hr = LineSetLineDevStatus(
  3593. &(pLine->t3Line),
  3594. LINEDEVSTATUSFLAGS_MSGWAIT,
  3595. fMessageWaiting?-1:0
  3596. );
  3597. if ( ((LONG)hr) < 0 )
  3598. {
  3599. LOG((TL_TRACE, "put_MessageWaiting failed sync - %lx", hr));
  3600. MaybeCloseALine( &pLine );
  3601. return hr;
  3602. }
  3603. // Wait for the async reply & map it's tapi2 code T3
  3604. hr = WaitForReply( hr );
  3605. MaybeCloseALine( &pLine );
  3606. if ( !SUCCEEDED(hr) )
  3607. {
  3608. LOG((TL_TRACE, "put_MessageWaiting failed async - %lx", hr));
  3609. return hr;
  3610. }
  3611. LOG((TL_TRACE, "put_MessageWaiting - Exit"));
  3612. return S_OK;
  3613. }
  3614. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3615. //
  3616. //
  3617. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3618. STDMETHODIMP
  3619. CAddress::get_MessageWaiting(
  3620. VARIANT_BOOL * pfMessageWaiting
  3621. )
  3622. {
  3623. HRESULT hr = S_OK;
  3624. LINEDEVSTATUS * pDevStatus;
  3625. AddressLineStruct * pLine;
  3626. LOG((TL_TRACE, "get_MessageWaiting - Enter"));
  3627. if (TAPIIsBadWritePtr(pfMessageWaiting , sizeof(VARIANT_BOOL) ) )
  3628. {
  3629. LOG((TL_ERROR, "get_MessageWaiting - bad pointer"));
  3630. return E_POINTER;
  3631. }
  3632. hr = FindOrOpenALine(
  3633. LINEMEDIAMODE_INTERACTIVEVOICE,
  3634. &pLine
  3635. );
  3636. if ( !SUCCEEDED(hr) )
  3637. {
  3638. LOG((TL_ERROR, "FindOrOpenALine failed - %lx", hr ));
  3639. return hr;
  3640. }
  3641. hr = LineGetLineDevStatus(
  3642. pLine->t3Line.hLine,
  3643. &pDevStatus
  3644. );
  3645. MaybeCloseALine( &pLine );
  3646. if ( !SUCCEEDED( hr ) )
  3647. {
  3648. LOG((TL_ERROR, "LineGetDevStatus failed - %lx", hr ));
  3649. return hr;
  3650. }
  3651. if ( pDevStatus->dwDevStatusFlags & LINEDEVSTATUSFLAGS_MSGWAIT )
  3652. {
  3653. *pfMessageWaiting = VARIANT_TRUE;
  3654. }
  3655. else
  3656. {
  3657. *pfMessageWaiting = VARIANT_FALSE;
  3658. }
  3659. ClientFree( pDevStatus );
  3660. if ( !SUCCEEDED(hr) )
  3661. {
  3662. LOG((TL_ERROR, "Bad pointer in get_MessageWaiting"));
  3663. return hr;
  3664. }
  3665. LOG((TL_TRACE, "get_MessageWaiting - Exit"));
  3666. return hr;
  3667. }
  3668. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3669. //
  3670. //
  3671. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3672. STDMETHODIMP
  3673. CAddress::put_DoNotDisturb(
  3674. VARIANT_BOOL fDoNotDisturb
  3675. )
  3676. {
  3677. HRESULT hr = S_OK;
  3678. LINEFORWARDLIST lfl;
  3679. HCALL hCall = NULL;
  3680. AddressLineStruct * pLine;
  3681. //
  3682. // do not disturb is acheived through calling
  3683. // lineforward with NULL for the dest address
  3684. //
  3685. LOG((TL_TRACE, "put_DoNotDisturb - Enter"));
  3686. //
  3687. // if we are setting dnd, create a lineforwardlist
  3688. // structure
  3689. //
  3690. if ( fDoNotDisturb )
  3691. {
  3692. ZeroMemory(
  3693. &lfl,
  3694. sizeof( LINEFORWARDLIST )
  3695. );
  3696. lfl.dwTotalSize = sizeof( LINEFORWARDLIST );
  3697. lfl.dwNumEntries = 1;
  3698. //
  3699. // there is only one item, and the dest address
  3700. // is NULL
  3701. //
  3702. lfl.ForwardList[0].dwForwardMode = LINEFORWARDMODE_UNCOND;
  3703. }
  3704. //
  3705. // get a line to use
  3706. //
  3707. hr = FindOrOpenALine(
  3708. LINEMEDIAMODE_INTERACTIVEVOICE,
  3709. &pLine
  3710. );
  3711. if ( !SUCCEEDED(hr) )
  3712. {
  3713. LOG((TL_ERROR, "put_DoNotDisturb - FindOrOpen failed %lx", hr));
  3714. return hr;
  3715. }
  3716. //
  3717. // call line forward
  3718. // if fDND is false, the LINEFORWARDLIST structure pointer
  3719. // should be NULL. This clears any fowarding on that
  3720. // line.
  3721. //
  3722. hr = LineForward(
  3723. &(pLine->t3Line),
  3724. m_dwAddressID,
  3725. fDoNotDisturb?&lfl:NULL,
  3726. 0,
  3727. &hCall
  3728. );
  3729. if ( ((long)hr) < 0 )
  3730. {
  3731. LOG((TL_ERROR, "put_DND - linefoward failed sync - %lx", hr));
  3732. MaybeCloseALine( &pLine );
  3733. return hr;
  3734. }
  3735. // Wait for the async reply & map it's tapi2 code T3
  3736. hr = WaitForReply( hr );
  3737. if ( NULL != hCall )
  3738. {
  3739. T3CALL t3Call;
  3740. HRESULT hr2;
  3741. t3Call.hCall = hCall;
  3742. hr2 = LineDrop(
  3743. t3Call.hCall,
  3744. NULL,
  3745. 0
  3746. );
  3747. if ( ((long)hr2) > 0 )
  3748. {
  3749. hr2 = WaitForReply( hr2 ) ;
  3750. }
  3751. hr2 = LineDeallocateCall(
  3752. t3Call.hCall
  3753. );
  3754. }
  3755. //
  3756. // we are no longer using the line
  3757. //
  3758. MaybeCloseALine( &pLine );
  3759. if ( !SUCCEEDED(hr) )
  3760. {
  3761. LOG((TL_ERROR, "put_DND - linefoware failed async - %lx", hr));
  3762. return hr;
  3763. }
  3764. LOG((TL_TRACE, "put_DoNotDisturb - Exit"));
  3765. return hr;
  3766. }
  3767. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3768. //
  3769. //
  3770. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3771. STDMETHODIMP
  3772. CAddress::get_DoNotDisturb(
  3773. VARIANT_BOOL * pfDoNotDisturb
  3774. )
  3775. {
  3776. HRESULT hr = S_OK;
  3777. AddressLineStruct * pLine;
  3778. LINEADDRESSSTATUS * pAddressStatus;
  3779. LINEDEVSTATUS * pDevStatus = NULL;
  3780. //
  3781. // donotdisturb is implemented through
  3782. // line forward.
  3783. // to get_DND, check the forward state
  3784. //
  3785. LOG((TL_TRACE, "get_DoNotDisturb - Enter"));
  3786. if (TAPIIsBadWritePtr(pfDoNotDisturb , sizeof(VARIANT_BOOL) ) )
  3787. {
  3788. LOG((TL_ERROR, "pfDoNotDisturb - bad pointer"));
  3789. return E_POINTER;
  3790. }
  3791. hr = FindOrOpenALine(
  3792. LINEMEDIAMODE_INTERACTIVEVOICE,
  3793. &pLine
  3794. );
  3795. if ( !SUCCEEDED(hr) )
  3796. {
  3797. LOG((TL_ERROR, "get_DND - FindOrOpen failed %lx", hr));
  3798. return hr;
  3799. }
  3800. hr = LineGetLineDevStatus(
  3801. pLine->t3Line.hLine,
  3802. &pDevStatus
  3803. );
  3804. if ( !SUCCEEDED(hr) )
  3805. {
  3806. MaybeCloseALine( &pLine );
  3807. return hr;
  3808. }
  3809. if ( !(pDevStatus->dwLineFeatures & LINEFEATURE_FORWARD ) )
  3810. {
  3811. LOG((TL_INFO, "get_DND - not supported"));
  3812. MaybeCloseALine( &pLine );
  3813. if(pDevStatus != NULL)
  3814. {
  3815. ClientFree(pDevStatus);
  3816. }
  3817. return TAPI_E_NOTSUPPORTED;
  3818. }
  3819. // finished with pDevStatus
  3820. if(pDevStatus != NULL)
  3821. {
  3822. ClientFree(pDevStatus);
  3823. }
  3824. //
  3825. // get the addresss status
  3826. //
  3827. hr = LineGetAddressStatus(
  3828. &(pLine->t3Line),
  3829. m_dwAddressID,
  3830. &pAddressStatus
  3831. );
  3832. if ( !SUCCEEDED(hr) )
  3833. {
  3834. LOG((TL_ERROR, "get_DND - LineGetAddressStatus failed - %lx", hr));
  3835. MaybeCloseALine( &pLine );
  3836. return hr;
  3837. }
  3838. //
  3839. // initialize to false
  3840. //
  3841. *pfDoNotDisturb = VARIANT_FALSE;
  3842. if ( !SUCCEEDED(hr) )
  3843. {
  3844. LOG((TL_ERROR, "get_DND - bad pointer"));
  3845. return E_OUTOFMEMORY;
  3846. }
  3847. //
  3848. // if there is forwarding
  3849. //
  3850. if ( 0 != pAddressStatus->dwForwardNumEntries )
  3851. {
  3852. LINEFORWARD * pfl;
  3853. pfl = (LINEFORWARD *) (((LPBYTE)pAddressStatus) + pAddressStatus->dwForwardOffset);
  3854. //
  3855. // and the dest address is NULL
  3856. //
  3857. if ( 0 == pfl->dwDestAddressOffset )
  3858. {
  3859. //
  3860. // DND is set
  3861. //
  3862. *pfDoNotDisturb = VARIANT_TRUE;
  3863. }
  3864. }
  3865. MaybeCloseALine( &pLine );
  3866. ClientFree( pAddressStatus );
  3867. LOG((TL_TRACE, "get_DoNotDisturb - Exit"));
  3868. return S_OK;
  3869. }
  3870. //
  3871. // itaddresscapabilities
  3872. //
  3873. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3874. //
  3875. //
  3876. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3877. STDMETHODIMP
  3878. CAddress::get_AddressCapability(
  3879. ADDRESS_CAPABILITY AddressCap,
  3880. long * plCapability
  3881. )
  3882. {
  3883. HRESULT hr = S_OK;
  3884. LOG((TL_TRACE, "get_AddressCapability - Enter"));
  3885. if ( TAPIIsBadWritePtr( plCapability, sizeof(long) ) )
  3886. {
  3887. LOG((TL_ERROR, "get_AddressCapability - bad pointer"));
  3888. return E_POINTER;
  3889. }
  3890. Lock();
  3891. hr = UpdateAddressCaps();
  3892. if ( !SUCCEEDED(hr) )
  3893. {
  3894. LOG((TL_ERROR, "get_AddressCapability - could not get addresscaps"));
  3895. Unlock();
  3896. return E_UNEXPECTED;
  3897. }
  3898. switch (AddressCap)
  3899. {
  3900. case AC_LINEID:
  3901. *plCapability = m_dwDeviceID;
  3902. break;
  3903. case AC_ADDRESSID:
  3904. *plCapability = m_dwAddressID;
  3905. break;
  3906. case AC_ADDRESSTYPES:
  3907. case AC_BEARERMODES:
  3908. case AC_MONITORDIGITSUPPORT:
  3909. case AC_GENERATEDIGITSUPPORT:
  3910. case AC_GENERATETONEMODES:
  3911. case AC_GENERATETONEMAXNUMFREQ:
  3912. case AC_MONITORTONEMAXNUMFREQ:
  3913. case AC_MONITORTONEMAXNUMENTRIES:
  3914. case AC_DEVCAPFLAGS:
  3915. case AC_ANSWERMODES:
  3916. case AC_LINEFEATURES:
  3917. case AC_SETTABLEDEVSTATUS:
  3918. case AC_PERMANENTDEVICEID:
  3919. case AC_GATHERDIGITSMINTIMEOUT:
  3920. case AC_GATHERDIGITSMAXTIMEOUT:
  3921. case AC_GENERATEDIGITMINDURATION:
  3922. case AC_GENERATEDIGITMAXDURATION:
  3923. case AC_GENERATEDIGITDEFAULTDURATION:
  3924. {
  3925. hr = UpdateLineDevCaps();
  3926. if ( !SUCCEEDED(hr) )
  3927. {
  3928. LOG((TL_ERROR, "get_AddressCap - could not get devcaps - %lx", hr));
  3929. Unlock();
  3930. return hr;
  3931. }
  3932. switch (AddressCap)
  3933. {
  3934. case AC_ADDRESSTYPES:
  3935. if ( m_dwAPIVersion >= TAPI_VERSION3_0 )
  3936. {
  3937. *plCapability = m_pDevCaps->dwAddressTypes;
  3938. }
  3939. else
  3940. {
  3941. *plCapability = LINEADDRESSTYPE_PHONENUMBER;
  3942. }
  3943. break;
  3944. case AC_BEARERMODES:
  3945. *plCapability = m_pDevCaps->dwBearerModes;
  3946. break;
  3947. case AC_MONITORDIGITSUPPORT:
  3948. *plCapability = m_pDevCaps->dwMonitorDigitModes;
  3949. break;
  3950. case AC_GENERATEDIGITSUPPORT:
  3951. *plCapability = m_pDevCaps->dwGenerateDigitModes;
  3952. break;
  3953. case AC_GENERATETONEMODES:
  3954. *plCapability = m_pDevCaps->dwGenerateToneModes;
  3955. break;
  3956. case AC_GENERATETONEMAXNUMFREQ:
  3957. *plCapability = m_pDevCaps->dwGenerateToneMaxNumFreq;
  3958. break;
  3959. case AC_MONITORTONEMAXNUMFREQ:
  3960. *plCapability = m_pDevCaps->dwMonitorToneMaxNumFreq;
  3961. break;
  3962. case AC_MONITORTONEMAXNUMENTRIES:
  3963. *plCapability = m_pDevCaps->dwMonitorToneMaxNumEntries;
  3964. break;
  3965. case AC_DEVCAPFLAGS:
  3966. *plCapability = m_pDevCaps->dwDevCapFlags;
  3967. break;
  3968. case AC_ANSWERMODES:
  3969. *plCapability = m_pDevCaps->dwAnswerMode;
  3970. break;
  3971. case AC_LINEFEATURES:
  3972. *plCapability = m_pDevCaps->dwLineFeatures;
  3973. break;
  3974. case AC_SETTABLEDEVSTATUS:
  3975. if ( m_dwAPIVersion >= TAPI_VERSION2_0 )
  3976. {
  3977. *plCapability = m_pDevCaps->dwSettableDevStatus;
  3978. }
  3979. else
  3980. hr = TAPI_E_NOTSUPPORTED;
  3981. break;
  3982. case AC_PERMANENTDEVICEID:
  3983. *plCapability = m_pDevCaps->dwPermanentLineID;
  3984. break;
  3985. case AC_GATHERDIGITSMINTIMEOUT:
  3986. *plCapability = m_pDevCaps->dwGatherDigitsMinTimeout;
  3987. break;
  3988. case AC_GATHERDIGITSMAXTIMEOUT:
  3989. *plCapability = m_pDevCaps->dwGatherDigitsMaxTimeout;
  3990. break;
  3991. case AC_GENERATEDIGITMINDURATION:
  3992. *plCapability = m_pDevCaps->MinDialParams.dwDigitDuration;
  3993. break;
  3994. case AC_GENERATEDIGITMAXDURATION:
  3995. *plCapability = m_pDevCaps->MaxDialParams.dwDigitDuration;
  3996. break;
  3997. case AC_GENERATEDIGITDEFAULTDURATION:
  3998. *plCapability = m_pDevCaps->DefaultDialParams.dwDigitDuration;
  3999. break;
  4000. }
  4001. break;
  4002. }
  4003. case AC_MAXACTIVECALLS:
  4004. case AC_MAXONHOLDCALLS:
  4005. case AC_MAXONHOLDPENDINGCALLS:
  4006. case AC_MAXNUMCONFERENCE:
  4007. case AC_MAXNUMTRANSCONF:
  4008. case AC_PARKSUPPORT:
  4009. case AC_CALLERIDSUPPORT:
  4010. case AC_CALLEDIDSUPPORT:
  4011. case AC_CONNECTEDIDSUPPORT:
  4012. case AC_REDIRECTIONIDSUPPORT:
  4013. case AC_REDIRECTINGIDSUPPORT:
  4014. case AC_ADDRESSCAPFLAGS:
  4015. case AC_CALLFEATURES1:
  4016. case AC_CALLFEATURES2:
  4017. case AC_REMOVEFROMCONFCAPS:
  4018. case AC_REMOVEFROMCONFSTATE:
  4019. case AC_TRANSFERMODES:
  4020. case AC_ADDRESSFEATURES:
  4021. case AC_PREDICTIVEAUTOTRANSFERSTATES:
  4022. case AC_MAXCALLDATASIZE:
  4023. case AC_FORWARDMODES:
  4024. case AC_MAXFORWARDENTRIES:
  4025. case AC_MAXSPECIFICENTRIES:
  4026. case AC_MINFWDNUMRINGS:
  4027. case AC_MAXFWDNUMRINGS:
  4028. case AC_MAXCALLCOMPLETIONS:
  4029. case AC_CALLCOMPLETIONCONDITIONS:
  4030. case AC_CALLCOMPLETIONMODES:
  4031. {
  4032. hr = UpdateAddressCaps();
  4033. if ( !SUCCEEDED(hr) )
  4034. {
  4035. LOG((TL_ERROR, "get_AddressCaps - could not update caps - %lx", hr));
  4036. Unlock();
  4037. return hr;
  4038. }
  4039. switch (AddressCap)
  4040. {
  4041. case AC_MAXACTIVECALLS:
  4042. *plCapability = m_pAddressCaps->dwMaxNumActiveCalls;
  4043. break;
  4044. case AC_MAXONHOLDCALLS:
  4045. *plCapability = m_pAddressCaps->dwMaxNumOnHoldCalls;
  4046. break;
  4047. case AC_MAXONHOLDPENDINGCALLS:
  4048. *plCapability = m_pAddressCaps->dwMaxNumOnHoldPendingCalls;
  4049. break;
  4050. case AC_MAXNUMCONFERENCE:
  4051. *plCapability = m_pAddressCaps->dwMaxNumConference;
  4052. break;
  4053. case AC_MAXNUMTRANSCONF:
  4054. *plCapability = m_pAddressCaps->dwMaxNumTransConf;
  4055. break;
  4056. case AC_PARKSUPPORT:
  4057. *plCapability = m_pAddressCaps->dwParkModes;
  4058. break;
  4059. case AC_CALLERIDSUPPORT:
  4060. *plCapability = m_pAddressCaps->dwCallerIDFlags;
  4061. break;
  4062. case AC_CALLEDIDSUPPORT:
  4063. *plCapability = m_pAddressCaps->dwCalledIDFlags;
  4064. break;
  4065. case AC_CONNECTEDIDSUPPORT:
  4066. *plCapability = m_pAddressCaps->dwConnectedIDFlags;
  4067. break;
  4068. case AC_REDIRECTIONIDSUPPORT:
  4069. *plCapability = m_pAddressCaps->dwRedirectionIDFlags;
  4070. break;
  4071. case AC_REDIRECTINGIDSUPPORT:
  4072. *plCapability = m_pAddressCaps->dwRedirectingIDFlags;
  4073. break;
  4074. case AC_ADDRESSCAPFLAGS:
  4075. *plCapability = m_pAddressCaps->dwAddrCapFlags;
  4076. break;
  4077. case AC_CALLFEATURES1:
  4078. *plCapability = m_pAddressCaps->dwCallFeatures;
  4079. break;
  4080. case AC_CALLFEATURES2:
  4081. if ( m_dwAPIVersion < TAPI_VERSION2_0 )
  4082. {
  4083. hr = TAPI_E_NOTSUPPORTED;
  4084. }
  4085. else
  4086. {
  4087. *plCapability = m_pAddressCaps->dwCallFeatures2;
  4088. }
  4089. break;
  4090. case AC_REMOVEFROMCONFCAPS:
  4091. *plCapability = m_pAddressCaps->dwRemoveFromConfCaps;
  4092. break;
  4093. case AC_REMOVEFROMCONFSTATE:
  4094. *plCapability = m_pAddressCaps->dwRemoveFromConfState;
  4095. break;
  4096. case AC_TRANSFERMODES:
  4097. *plCapability = m_pAddressCaps->dwTransferModes;
  4098. break;
  4099. case AC_ADDRESSFEATURES:
  4100. *plCapability = m_pAddressCaps->dwAddressFeatures;
  4101. break;
  4102. case AC_PREDICTIVEAUTOTRANSFERSTATES:
  4103. if ( m_dwAPIVersion < TAPI_VERSION2_0 )
  4104. {
  4105. hr = TAPI_E_NOTSUPPORTED;
  4106. }
  4107. else
  4108. {
  4109. *plCapability = m_pAddressCaps->dwPredictiveAutoTransferStates;
  4110. }
  4111. break;
  4112. case AC_MAXCALLDATASIZE:
  4113. if ( m_dwAPIVersion < TAPI_VERSION2_0 )
  4114. {
  4115. hr = TAPI_E_NOTSUPPORTED;
  4116. }
  4117. else
  4118. {
  4119. *plCapability = m_pAddressCaps->dwMaxCallDataSize;
  4120. }
  4121. break;
  4122. case AC_FORWARDMODES:
  4123. *plCapability = m_pAddressCaps->dwForwardModes;
  4124. break;
  4125. case AC_MAXFORWARDENTRIES:
  4126. *plCapability = m_pAddressCaps->dwMaxForwardEntries;
  4127. break;
  4128. case AC_MAXSPECIFICENTRIES:
  4129. *plCapability = m_pAddressCaps->dwMaxSpecificEntries;
  4130. break;
  4131. case AC_MINFWDNUMRINGS:
  4132. *plCapability = m_pAddressCaps->dwMinFwdNumRings;
  4133. break;
  4134. case AC_MAXFWDNUMRINGS:
  4135. *plCapability = m_pAddressCaps->dwMaxFwdNumRings;
  4136. break;
  4137. case AC_MAXCALLCOMPLETIONS:
  4138. *plCapability = m_pAddressCaps->dwMaxCallCompletions;
  4139. break;
  4140. case AC_CALLCOMPLETIONCONDITIONS:
  4141. *plCapability = m_pAddressCaps->dwCallCompletionConds;
  4142. break;
  4143. case AC_CALLCOMPLETIONMODES:
  4144. *plCapability = m_pAddressCaps->dwCallCompletionModes;
  4145. break;
  4146. }
  4147. break;
  4148. }
  4149. default:
  4150. LOG((TL_ERROR, "get_AddressCapability - bad addrcap"));
  4151. Unlock();
  4152. return E_INVALIDARG;
  4153. }
  4154. LOG((TL_TRACE, "get_AddressCapability - Exit - result - %lx", hr));
  4155. Unlock();
  4156. return hr;
  4157. }
  4158. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4159. //
  4160. //
  4161. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4162. STDMETHODIMP
  4163. CAddress::get_AddressCapabilityString(
  4164. ADDRESS_CAPABILITY_STRING AddressCapString,
  4165. BSTR * ppCapabilityString
  4166. )
  4167. {
  4168. HRESULT hr = S_OK;
  4169. LOG((TL_TRACE, "get_AddressCapabilityString - Enter"));
  4170. if ( TAPIIsBadWritePtr( ppCapabilityString, sizeof(BSTR) ) )
  4171. {
  4172. LOG((TL_ERROR, "get_AddressCapabilityString - bad pointer"));
  4173. return E_POINTER;
  4174. }
  4175. *ppCapabilityString = NULL;
  4176. Lock();
  4177. //
  4178. // note on:
  4179. // ACS_ADDRESSDEVICESPECIFIC
  4180. // ACS_LINEDEVICESPECIFIC:
  4181. // ACS_PROVIDERSPECIFIC:
  4182. // ACS_SWITCHSPECIFIC:
  4183. //
  4184. // These buffers in LINEDEVCAPS and LINEADDRESSCAPS may or may not be strings. However
  4185. // in TAPI 3, we define them as strings.
  4186. //
  4187. // The algorithm for moving them from the tapi 2 structure to the tapi 3 string is:
  4188. //
  4189. // if the size of the buffer is evenly divisible by sizeof(WCHAR)
  4190. // then it's definitely not a string (we only support WCHAR)
  4191. // so we will just copy the buffer straight into the returned string, and append a
  4192. // NULL at the end
  4193. // else
  4194. // if the buffer already has a null at the end, don't copy it, because SysAllocStringByteLen
  4195. // always appends a NULL and double NULLs frighten VB.
  4196. //
  4197. // It can still be a "buffer" and not a string even if it is divisible by sizeof WCHAR, but for
  4198. // this it does matter, since we are using SysAllocStringByteLen to copy the buffer no
  4199. // matter what
  4200. //
  4201. switch (AddressCapString)
  4202. {
  4203. case ACS_ADDRESSDEVICESPECIFIC:
  4204. hr = UpdateAddressCaps();
  4205. if ( !SUCCEEDED(hr) )
  4206. {
  4207. Unlock();
  4208. return hr;
  4209. }
  4210. if ( m_pAddressCaps->dwDevSpecificSize != 0 )
  4211. {
  4212. LPWSTR pHold;
  4213. DWORD dwSize;
  4214. dwSize = m_pAddressCaps->dwDevSpecificSize;
  4215. //
  4216. // is size divisible by sizeof(WCHAR)?
  4217. //
  4218. if (0 == (dwSize % sizeof(WCHAR)))
  4219. {
  4220. //
  4221. // yes - get to the last character in the string
  4222. //
  4223. pHold = (LPWSTR)(((LPBYTE)(m_pAddressCaps)) + m_pAddressCaps->dwDevSpecificOffset),
  4224. (dwSize-sizeof(WCHAR))/sizeof(WCHAR);
  4225. //
  4226. // is the last character a NULL?
  4227. //
  4228. if (*pHold == NULL)
  4229. {
  4230. //
  4231. // yes, so don't copy it
  4232. //
  4233. dwSize-=sizeof(WCHAR);
  4234. }
  4235. }
  4236. //
  4237. // Alloc and copy into return string. SysAllocStringByteLen always
  4238. // appends a NULL
  4239. //
  4240. *ppCapabilityString = SysAllocStringByteLen(
  4241. (LPSTR)(((LPBYTE)(m_pAddressCaps)) + m_pAddressCaps->dwDevSpecificOffset),
  4242. dwSize
  4243. );
  4244. if ( NULL == *ppCapabilityString )
  4245. {
  4246. LOG((TL_ERROR, "get_AddressCapabilityString - SysAllocString Failed"));
  4247. hr = E_OUTOFMEMORY;
  4248. }
  4249. }
  4250. break;
  4251. case ACS_PROTOCOL:
  4252. case ACS_LINEDEVICESPECIFIC:
  4253. case ACS_PROVIDERSPECIFIC:
  4254. case ACS_SWITCHSPECIFIC:
  4255. case ACS_PERMANENTDEVICEGUID:
  4256. {
  4257. hr = UpdateLineDevCaps();
  4258. if ( !SUCCEEDED(hr) )
  4259. {
  4260. Unlock();
  4261. return hr;
  4262. }
  4263. switch (AddressCapString)
  4264. {
  4265. case ACS_PROTOCOL:
  4266. {
  4267. LPWSTR pwstr;
  4268. if ( m_dwAPIVersion >= TAPI_VERSION3_0 )
  4269. {
  4270. IID iid;
  4271. iid = m_pDevCaps->ProtocolGuid;
  4272. StringFromIID(iid, &pwstr);
  4273. }
  4274. else
  4275. {
  4276. StringFromIID( TAPIPROTOCOL_PSTN, &pwstr );
  4277. }
  4278. *ppCapabilityString = SysAllocString( pwstr );
  4279. if ( NULL == *ppCapabilityString )
  4280. {
  4281. LOG((TL_ERROR, "get_AddressCapabilityString - SysAllocString Failed"));
  4282. hr = E_OUTOFMEMORY;
  4283. }
  4284. CoTaskMemFree( pwstr );
  4285. break;
  4286. }
  4287. case ACS_LINEDEVICESPECIFIC:
  4288. if ( m_pDevCaps->dwDevSpecificSize != 0 )
  4289. {
  4290. LPWSTR pHold;
  4291. DWORD dwSize;
  4292. dwSize = m_pDevCaps->dwDevSpecificSize;
  4293. //
  4294. // is size divisible by sizeof(WCHAR)?
  4295. //
  4296. if (0 == (dwSize % sizeof(WCHAR)))
  4297. {
  4298. //
  4299. // yes - get to the last character in the string
  4300. //
  4301. pHold = (LPWSTR)(((LPBYTE)(m_pDevCaps)) + m_pDevCaps->dwDevSpecificOffset) +
  4302. (dwSize-sizeof(WCHAR))/sizeof(WCHAR);
  4303. //
  4304. // is the last character a NULL?
  4305. //
  4306. if (*pHold == NULL)
  4307. {
  4308. //
  4309. // yes, so don't copy it
  4310. //
  4311. dwSize-=sizeof(WCHAR);
  4312. }
  4313. }
  4314. //
  4315. // Alloc and copy into return string. SysAllocStringByteLen always
  4316. // appends a NULL
  4317. //
  4318. *ppCapabilityString = SysAllocStringByteLen(
  4319. (LPSTR)(((LPBYTE)(m_pDevCaps)) + m_pDevCaps->dwDevSpecificOffset),
  4320. dwSize
  4321. );
  4322. if ( NULL == *ppCapabilityString )
  4323. {
  4324. LOG((TL_ERROR, "get_AddressCapabilityString - SysAllocString Failed"));
  4325. hr = E_OUTOFMEMORY;
  4326. }
  4327. }
  4328. break;
  4329. case ACS_PROVIDERSPECIFIC:
  4330. if ( m_pDevCaps->dwProviderInfoSize != 0 )
  4331. {
  4332. LPWSTR pHold;
  4333. DWORD dwSize;
  4334. dwSize = m_pDevCaps->dwProviderInfoSize;
  4335. //
  4336. // is size divisible by sizeof(WCHAR)?
  4337. //
  4338. if (0 == (dwSize % sizeof(WCHAR)))
  4339. {
  4340. //
  4341. // yes - get to the last character in the string
  4342. //
  4343. pHold = (LPWSTR)(((LPBYTE)(m_pDevCaps)) + m_pDevCaps->dwProviderInfoOffset) +
  4344. (dwSize-sizeof(WCHAR))/sizeof(WCHAR);
  4345. //
  4346. // is the last character a NULL?
  4347. //
  4348. if (*pHold == NULL)
  4349. {
  4350. //
  4351. // yes, so don't copy it
  4352. //
  4353. dwSize-=sizeof(WCHAR);
  4354. }
  4355. }
  4356. //
  4357. // Alloc and copy into return string. SysAllocStringByteLen always
  4358. // appends a NULL
  4359. //
  4360. *ppCapabilityString = SysAllocStringByteLen(
  4361. (LPSTR)(((LPBYTE)(m_pDevCaps)) + m_pDevCaps->dwProviderInfoOffset),
  4362. dwSize
  4363. );
  4364. if ( NULL == *ppCapabilityString )
  4365. {
  4366. LOG((TL_ERROR, "get_AddressCapabilityString - SysAllocString Failed"));
  4367. hr = E_OUTOFMEMORY;
  4368. }
  4369. }
  4370. break;
  4371. case ACS_SWITCHSPECIFIC:
  4372. if ( m_pDevCaps->dwSwitchInfoSize != 0 )
  4373. {
  4374. LPWSTR pHold;
  4375. DWORD dwSize;
  4376. dwSize = m_pDevCaps->dwSwitchInfoSize;
  4377. //
  4378. // is size divisible by sizeof(WCHAR)?
  4379. //
  4380. if (0 == (dwSize % sizeof(WCHAR)))
  4381. {
  4382. //
  4383. // yes - get to the last character in the string
  4384. //
  4385. pHold = (LPWSTR)(((LPBYTE)(m_pDevCaps)) + m_pDevCaps->dwSwitchInfoOffset) +
  4386. (dwSize-sizeof(WCHAR))/sizeof(WCHAR);
  4387. //
  4388. // is the last character a NULL?
  4389. //
  4390. if (*pHold == NULL)
  4391. {
  4392. //
  4393. // yes, so don't copy it
  4394. //
  4395. dwSize-=sizeof(WCHAR);
  4396. }
  4397. }
  4398. //
  4399. // Alloc and copy into return string. SysAllocStringByteLen always
  4400. // appends a NULL
  4401. //
  4402. *ppCapabilityString = SysAllocStringByteLen(
  4403. (LPSTR)(((LPBYTE)(m_pDevCaps)) + m_pDevCaps->dwSwitchInfoOffset),
  4404. dwSize
  4405. );
  4406. if ( NULL == *ppCapabilityString )
  4407. {
  4408. LOG((TL_ERROR, "get_AddressCapabilityString - SysAllocString Failed"));
  4409. hr = E_OUTOFMEMORY;
  4410. }
  4411. }
  4412. break;
  4413. case ACS_PERMANENTDEVICEGUID:
  4414. {
  4415. LPWSTR pwstrGUIDText;
  4416. if ( m_dwAPIVersion >= TAPI_VERSION2_2 )
  4417. {
  4418. IID iid;
  4419. iid = m_pDevCaps->PermanentLineGuid;
  4420. StringFromIID(iid, &pwstrGUIDText);
  4421. *ppCapabilityString = SysAllocString( pwstrGUIDText );
  4422. if ( NULL == *ppCapabilityString )
  4423. {
  4424. LOG((TL_ERROR, "get_AddressCapabilityString - SysAllocString Failed"));
  4425. hr = E_OUTOFMEMORY;
  4426. }
  4427. CoTaskMemFree( pwstrGUIDText );
  4428. }
  4429. else
  4430. {
  4431. // return with NULL string & error code
  4432. hr = TAPI_E_NOTSUPPORTED;
  4433. }
  4434. break;
  4435. }
  4436. default:
  4437. break;
  4438. }
  4439. break;
  4440. }
  4441. default:
  4442. LOG((TL_ERROR, "get_AddressCapabilityString - invalid cap"));
  4443. Unlock();
  4444. return E_INVALIDARG;
  4445. }
  4446. LOG((TL_TRACE, "get_AddressCapabilityString - Exit - result - %lx", hr));
  4447. Unlock();
  4448. return hr;
  4449. }
  4450. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4451. //
  4452. //
  4453. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4454. HRESULT CreateBstrCollection(
  4455. IN BSTR * pBstr,
  4456. IN DWORD dwCount,
  4457. OUT VARIANT * pVariant
  4458. )
  4459. {
  4460. //
  4461. // create the collection object
  4462. //
  4463. CComObject<CTapiBstrCollection> * pCollection;
  4464. HRESULT hr = CComObject<CTapiBstrCollection>::CreateInstance( &pCollection );
  4465. if ( FAILED(hr) )
  4466. {
  4467. LOG((TL_ERROR, "CreateBstrCollection - "
  4468. "can't create collection - exit 0x%lx", hr));
  4469. return hr;
  4470. }
  4471. //
  4472. // get the Collection's IDispatch interface
  4473. //
  4474. IDispatch * pDispatch;
  4475. hr = pCollection->_InternalQueryInterface(__uuidof(IDispatch),
  4476. (void **) &pDispatch );
  4477. if ( FAILED(hr) )
  4478. {
  4479. LOG((TL_ERROR, "CreateBstrCollection - "
  4480. "QI for IDispatch on collection failed - exit 0x%lx", hr));
  4481. delete pCollection;
  4482. return hr;
  4483. }
  4484. //
  4485. // Init the collection using an iterator -- pointers to the beginning and
  4486. // the ending element plus one.
  4487. //
  4488. hr = pCollection->Initialize( dwCount,
  4489. pBstr,
  4490. pBstr + dwCount);
  4491. if ( FAILED(hr) )
  4492. {
  4493. LOG((TL_ERROR, "CreateBstrCollection - "
  4494. "Initialize on collection failed - exit 0x%lx", hr));
  4495. pDispatch->Release();
  4496. return hr;
  4497. }
  4498. //
  4499. // put the IDispatch interface pointer into the variant
  4500. //
  4501. LOG((TL_ERROR, "CreateBstrCollection - "
  4502. "placing IDispatch value %p in variant", pDispatch));
  4503. VariantInit(pVariant);
  4504. pVariant->vt = VT_DISPATCH;
  4505. pVariant->pdispVal = pDispatch;
  4506. LOG((TL_TRACE, "CreateBstrCollection - exit S_OK"));
  4507. return S_OK;
  4508. }
  4509. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4510. //
  4511. //
  4512. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4513. HRESULT CreateBstrEnumerator(
  4514. IN BSTR * begin,
  4515. IN BSTR * end,
  4516. OUT IEnumBstr ** ppIEnum
  4517. )
  4518. {
  4519. typedef CSafeComEnum<IEnumBstr, &__uuidof(IEnumBstr), BSTR, _CopyBSTR> CEnumerator;
  4520. HRESULT hr;
  4521. CComObject<CEnumerator> *pEnum = NULL;
  4522. hr = CComObject<CEnumerator>::CreateInstance(&pEnum);
  4523. if (pEnum == NULL)
  4524. {
  4525. LOG((TL_ERROR, "CreateBstrEnumerator - "
  4526. "Could not create enumerator object, 0x%lx", hr));
  4527. return hr;
  4528. }
  4529. IEnumBstr * pIEnum;
  4530. hr = pEnum->_InternalQueryInterface(
  4531. __uuidof(IEnumBstr),
  4532. (void**)&pIEnum
  4533. );
  4534. if (FAILED(hr))
  4535. {
  4536. LOG((TL_ERROR, "CreateBstrEnumerator - "
  4537. "query enum interface failed, 0x%lx", hr));
  4538. delete pEnum;
  4539. return hr;
  4540. }
  4541. hr = pEnum->Init(begin, end, NULL, AtlFlagCopy);
  4542. if (FAILED(hr))
  4543. {
  4544. LOG((TL_ERROR, "CreateBstrEnumerator - "
  4545. "init enumerator object failed, 0x%lx", hr));
  4546. pIEnum->Release();
  4547. return hr;
  4548. }
  4549. *ppIEnum = pIEnum;
  4550. LOG((TL_TRACE, "CreateBstrEnumerator - exit S_OK"));
  4551. return S_OK;
  4552. }
  4553. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4554. //
  4555. //
  4556. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4557. STDMETHODIMP
  4558. CAddress::get_CallTreatments(VARIANT * pVariant )
  4559. {
  4560. HRESULT hr = E_NOTIMPL;
  4561. LOG((TL_TRACE, "get_CallTreatments - Enter"));
  4562. LOG((TL_TRACE, "get_CallTreatments - Exit - result - %lx", hr));
  4563. return hr;
  4564. }
  4565. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4566. //
  4567. //
  4568. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4569. STDMETHODIMP
  4570. CAddress::EnumerateCallTreatments(IEnumBstr ** ppEnumCallTreatment )
  4571. {
  4572. HRESULT hr = E_NOTIMPL;
  4573. LOG((TL_TRACE, "EnumerateCallTreatments - Enter"));
  4574. LOG((TL_TRACE, "EnumerateCallTreatments - Exit - result - %lx", hr));
  4575. return hr;
  4576. }
  4577. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4578. //
  4579. //
  4580. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4581. STDMETHODIMP
  4582. CAddress::get_CompletionMessages(VARIANT * pVariant)
  4583. {
  4584. HRESULT hr = E_NOTIMPL;
  4585. LOG((TL_TRACE, "get_CompletionMessages - Enter"));
  4586. LOG((TL_TRACE, "get_CompletionMessages - Exit - result - %lx", hr));
  4587. return hr;
  4588. }
  4589. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4590. //
  4591. //
  4592. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4593. STDMETHODIMP
  4594. CAddress::EnumerateCompletionMessages(IEnumBstr ** ppEnumCompletionMessage)
  4595. {
  4596. HRESULT hr = E_NOTIMPL;
  4597. LOG((TL_TRACE, "EnumerateCompletionMessages - Enter"));
  4598. LOG((TL_TRACE, "EnumerateCompletionMessages - Exit - result - %lx", hr));
  4599. return hr;
  4600. }
  4601. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4602. //
  4603. //
  4604. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4605. STDMETHODIMP
  4606. CAddress::get_DeviceClasses(VARIANT * pVariant)
  4607. {
  4608. HRESULT hr = S_OK;
  4609. LOG((TL_TRACE, "get_DeviceClasses - Enter"));
  4610. //
  4611. // Check arguments.
  4612. //
  4613. if ( TAPIIsBadWritePtr( pVariant, sizeof( VARIANT ) ) )
  4614. {
  4615. LOG((TL_ERROR, "get_DeviceClasses - bad pointer"));
  4616. return E_POINTER;
  4617. }
  4618. Lock();
  4619. hr = UpdateLineDevCaps();
  4620. if ( SUCCEEDED(hr) )
  4621. {
  4622. if ( (m_dwAPIVersion >= TAPI_VERSION2_0) && (0 != m_pDevCaps->dwDeviceClassesOffset) )
  4623. {
  4624. PWSTR pszDevices;
  4625. DWORD dwNumDeviceClasses;
  4626. //
  4627. // first count the device classes
  4628. //
  4629. dwNumDeviceClasses = 0;
  4630. pszDevices = (PWSTR)( ( (PBYTE)m_pDevCaps ) + m_pDevCaps->dwDeviceClassesOffset );
  4631. while (NULL != *pszDevices)
  4632. {
  4633. dwNumDeviceClasses++;
  4634. pszDevices += (lstrlenW(pszDevices) + 1 );
  4635. }
  4636. //
  4637. // allocate an array of BSTR pointers
  4638. //
  4639. BSTR *DeviceClasses =
  4640. (BSTR *)ClientAlloc(sizeof(BSTR *) * dwNumDeviceClasses);
  4641. if (DeviceClasses == NULL)
  4642. {
  4643. LOG((TL_ERROR, "get_DeviceClasses - out of memory"));
  4644. Unlock();
  4645. return E_OUTOFMEMORY;
  4646. }
  4647. //
  4648. // allocate all the BSTRs, copying the device class names
  4649. //
  4650. DWORD dwCount = 0;
  4651. pszDevices = (PWSTR)( ( (PBYTE)m_pDevCaps ) + m_pDevCaps->dwDeviceClassesOffset );
  4652. for (DWORD i = 0; i < dwNumDeviceClasses; i++)
  4653. {
  4654. LOG((TL_INFO, "get_DeviceClasses - got '%ws'", pszDevices));
  4655. DeviceClasses[i] = SysAllocString(pszDevices);
  4656. if (DeviceClasses[i] == NULL)
  4657. {
  4658. LOG((TL_ERROR, "get_DeviceClasses - out of memory"));
  4659. hr = E_OUTOFMEMORY;
  4660. break;
  4661. }
  4662. dwCount++;
  4663. pszDevices += (lstrlenW(pszDevices) + 1 );
  4664. }
  4665. if ( FAILED(hr) )
  4666. {
  4667. // release all the BSTRs and the array.
  4668. for (i = 0; i < dwCount; i ++)
  4669. {
  4670. SysFreeString(DeviceClasses[i]);
  4671. }
  4672. ClientFree(DeviceClasses);
  4673. Unlock();
  4674. return hr;
  4675. }
  4676. hr = CreateBstrCollection(DeviceClasses, dwCount, pVariant);
  4677. // if the collection is not created, release all the BSTRs.
  4678. if (FAILED(hr))
  4679. {
  4680. LOG((TL_ERROR, "get_DeviceClasses - unable to create collection"));
  4681. for (i = 0; i < dwCount; i ++)
  4682. {
  4683. SysFreeString(DeviceClasses[i]);
  4684. }
  4685. }
  4686. // delete the pointer array.
  4687. ClientFree(DeviceClasses);
  4688. }
  4689. else
  4690. {
  4691. LOG((TL_ERROR, "get_DeviceClasses - no device classes"));
  4692. //
  4693. // create an empty collection
  4694. //
  4695. hr = CreateBstrCollection(NULL, 0, pVariant);
  4696. if (FAILED(hr))
  4697. {
  4698. LOG((TL_ERROR, "get_DeviceClasses - unable to create collection"));
  4699. }
  4700. }
  4701. }
  4702. Unlock();
  4703. LOG((TL_TRACE, "get_DeviceClasses - Exit - result - %lx", hr));
  4704. return hr;
  4705. }
  4706. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4707. //
  4708. //
  4709. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4710. STDMETHODIMP
  4711. CAddress::EnumerateDeviceClasses(IEnumBstr ** ppEnumDeviceClass)
  4712. {
  4713. HRESULT hr = S_OK;
  4714. LOG((TL_TRACE, "EnumerateDeviceClasses - Enter"));
  4715. //
  4716. // Check arguments.
  4717. //
  4718. if ( TAPIIsBadWritePtr( ppEnumDeviceClass, sizeof( IEnumBstr * ) ) )
  4719. {
  4720. LOG((TL_ERROR, "EnumerateDeviceClasses - bad pointer"));
  4721. return E_POINTER;
  4722. }
  4723. Lock();
  4724. hr = UpdateLineDevCaps();
  4725. if ( SUCCEEDED(hr) )
  4726. {
  4727. if ( (m_dwAPIVersion >= TAPI_VERSION2_0) && (0 != m_pDevCaps->dwDeviceClassesOffset) )
  4728. {
  4729. PWSTR pszDevices;
  4730. DWORD dwNumDeviceClasses;
  4731. //
  4732. // first count the device classes
  4733. //
  4734. dwNumDeviceClasses = 0;
  4735. pszDevices = (PWSTR)( ( (PBYTE)m_pDevCaps ) + m_pDevCaps->dwDeviceClassesOffset );
  4736. while (NULL != *pszDevices)
  4737. {
  4738. dwNumDeviceClasses++;
  4739. pszDevices += (lstrlenW(pszDevices) + 1 );
  4740. }
  4741. //
  4742. // allocate an array of BSTR pointers
  4743. //
  4744. BSTR *DeviceClasses =
  4745. (BSTR *)ClientAlloc(sizeof(BSTR *) * dwNumDeviceClasses);
  4746. if (DeviceClasses == NULL)
  4747. {
  4748. LOG((TL_ERROR, "EnumerateDeviceClasses - out of memory"));
  4749. Unlock();
  4750. return E_OUTOFMEMORY;
  4751. }
  4752. //
  4753. // allocate all the BSTRs, copying the device class names
  4754. //
  4755. DWORD dwCount = 0;
  4756. pszDevices = (PWSTR)( ( (PBYTE)m_pDevCaps ) + m_pDevCaps->dwDeviceClassesOffset );
  4757. for (DWORD i = 0; i < dwNumDeviceClasses; i++)
  4758. {
  4759. LOG((TL_INFO, "EnumerateDeviceClasses - got '%ws'", pszDevices));
  4760. DeviceClasses[i] = SysAllocString(pszDevices);
  4761. if (DeviceClasses[i] == NULL)
  4762. {
  4763. LOG((TL_ERROR, "EnumerateDeviceClasses - out of memory"));
  4764. hr = E_OUTOFMEMORY;
  4765. break;
  4766. }
  4767. dwCount++;
  4768. pszDevices += (lstrlenW(pszDevices) + 1 );
  4769. }
  4770. if ( FAILED(hr) )
  4771. {
  4772. // release all the BSTRs and the array.
  4773. for (i = 0; i < dwCount; i ++)
  4774. {
  4775. SysFreeString(DeviceClasses[i]);
  4776. }
  4777. ClientFree(DeviceClasses);
  4778. Unlock();
  4779. return hr;
  4780. }
  4781. hr = CreateBstrEnumerator(DeviceClasses, DeviceClasses + dwCount, ppEnumDeviceClass);
  4782. if (FAILED(hr))
  4783. {
  4784. LOG((TL_ERROR, "EnumerateDeviceClasses - unable to create enum"));
  4785. }
  4786. // release all the BSTRs as the enumerator made a copy of them
  4787. for (i = 0; i < dwCount; i ++)
  4788. {
  4789. SysFreeString(DeviceClasses[i]);
  4790. }
  4791. // delete the pointer array.
  4792. ClientFree(DeviceClasses);
  4793. }
  4794. else
  4795. {
  4796. LOG((TL_ERROR, "EnumerateDeviceClasses - no device classes"));
  4797. //
  4798. // create an empty enumeration
  4799. //
  4800. hr = CreateBstrEnumerator(NULL, NULL, ppEnumDeviceClass);
  4801. if (FAILED(hr))
  4802. {
  4803. LOG((TL_ERROR, "EnumerateDeviceClasses - unable to create enumeration"));
  4804. }
  4805. }
  4806. }
  4807. Unlock();
  4808. LOG((TL_TRACE, "EnumerateDeviceClasses - Exit - result - %lx", hr));
  4809. return hr;
  4810. }
  4811. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4812. //
  4813. //
  4814. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4815. void
  4816. HandleLineDevStateMessage(
  4817. CTAPI * pTapi,
  4818. PASYNCEVENTMSG pParams
  4819. )
  4820. {
  4821. LOG((TL_TRACE, "HandleLineDevStateMessage - enter. tapi[%p]", pTapi));
  4822. CAddress * pAddress;
  4823. if ( LINEDEVSTATE_REINIT == pParams->Param1 )
  4824. {
  4825. LOG((TL_TRACE, "HandleLineDevStateMessage - LINEDEVSTATE_REINIT"));
  4826. pTapi->AddRef();
  4827. //This is to remove the bug, 4 RE_INIT messages for two objects.
  4828. pTapi->HandleReinit();
  4829. pTapi->Release();
  4830. LOG((TL_TRACE, "HandleLineDevStateMessage - exit"));
  4831. return;
  4832. }
  4833. if ( LINEDEVSTATE_TRANSLATECHANGE == pParams->Param1 )
  4834. {
  4835. CTapiObjectEvent::FireEvent(
  4836. pTapi,
  4837. TE_TRANSLATECHANGE,
  4838. NULL,
  4839. 0,
  4840. NULL
  4841. );
  4842. return;
  4843. }
  4844. if ( !FindAddressObject(
  4845. (HLINE)(pParams->hDevice),
  4846. &pAddress
  4847. ) )
  4848. {
  4849. LOG((TL_WARN, "Can't process LINE_LINEDEVSTATE message"));
  4850. LOG((TL_WARN, " - cannot find hLine %lx", pParams->hDevice));
  4851. return;
  4852. }
  4853. switch ( pParams->Param1 )
  4854. {
  4855. case LINEDEVSTATE_CONNECTED:
  4856. case LINEDEVSTATE_INSERVICE:
  4857. {
  4858. pAddress->InService( pParams->Param1 );
  4859. break;
  4860. }
  4861. case LINEDEVSTATE_OUTOFSERVICE:
  4862. case LINEDEVSTATE_MAINTENANCE:
  4863. case LINEDEVSTATE_REMOVED:
  4864. case LINEDEVSTATE_DISCONNECTED:
  4865. case LINEDEVSTATE_LOCK:
  4866. pAddress->OutOfService( pParams->Param1 );
  4867. break;
  4868. case LINEDEVSTATE_MSGWAITON:
  4869. CAddressEvent::FireEvent(
  4870. pAddress,
  4871. AE_MSGWAITON,
  4872. NULL
  4873. );
  4874. break;
  4875. case LINEDEVSTATE_MSGWAITOFF:
  4876. CAddressEvent::FireEvent(
  4877. pAddress,
  4878. AE_MSGWAITOFF,
  4879. NULL
  4880. );
  4881. break;
  4882. // the line has been opened or
  4883. // closed by another app
  4884. case LINEDEVSTATE_OPEN:
  4885. case LINEDEVSTATE_CLOSE:
  4886. break;
  4887. case LINEDEVSTATE_CAPSCHANGE:
  4888. pAddress->CapsChange( FALSE );
  4889. break;
  4890. case LINEDEVSTATE_CONFIGCHANGE:
  4891. {
  4892. CAddressEvent::FireEvent(
  4893. pAddress,
  4894. AE_CONFIGCHANGE,
  4895. NULL
  4896. );
  4897. break;
  4898. }
  4899. case LINEDEVSTATE_RINGING:
  4900. {
  4901. CAddressEvent::FireEvent(
  4902. pAddress,
  4903. AE_RINGING,
  4904. NULL
  4905. );
  4906. break;
  4907. }
  4908. case LINEDEVSTATE_DEVSPECIFIC:
  4909. case LINEDEVSTATE_OTHER:
  4910. case LINEDEVSTATE_NUMCALLS:
  4911. case LINEDEVSTATE_NUMCOMPLETIONS:
  4912. case LINEDEVSTATE_TERMINALS:
  4913. case LINEDEVSTATE_ROAMMODE:
  4914. case LINEDEVSTATE_BATTERY:
  4915. case LINEDEVSTATE_SIGNAL:
  4916. case LINEDEVSTATE_COMPLCANCEL:
  4917. LOG((TL_INFO, "LINE_LINEDEVSTATE message not handled - %lx", pParams->Param1));
  4918. break;
  4919. default:
  4920. LOG((TL_WARN, "Unknown LINE_LINEDEVSTATE message - %lx", pParams->Param1));
  4921. break;
  4922. }
  4923. //FindAddressObject addrefs the address objct
  4924. pAddress->Release();
  4925. LOG((TL_TRACE, "HandleLineDevStateMessage - exit."));
  4926. return;
  4927. }
  4928. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4929. //
  4930. //
  4931. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4932. void
  4933. HandleAddressStateMessage(
  4934. PASYNCEVENTMSG pParams
  4935. )
  4936. {
  4937. CAddress * pAddress;
  4938. if ( !FindAddressObject(
  4939. (HLINE)(pParams->hDevice),
  4940. &pAddress
  4941. ) )
  4942. {
  4943. LOG((TL_WARN, "Can't process LINE_LINEDEVSTATE message"));
  4944. LOG((TL_WARN, " - cannot find hLine %lx", pParams->hDevice));
  4945. return;
  4946. }
  4947. switch ( pParams->Param1 )
  4948. {
  4949. case LINEADDRESSSTATE_FORWARD:
  4950. {
  4951. CAddressEvent::FireEvent(
  4952. pAddress,
  4953. AE_FORWARD,
  4954. NULL
  4955. );
  4956. break;
  4957. }
  4958. case LINEADDRESSSTATE_CAPSCHANGE:
  4959. {
  4960. pAddress->CapsChange( TRUE );
  4961. break;
  4962. }
  4963. case LINEADDRESSSTATE_OTHER:
  4964. case LINEADDRESSSTATE_DEVSPECIFIC:
  4965. case LINEADDRESSSTATE_INUSEZERO:
  4966. case LINEADDRESSSTATE_INUSEONE:
  4967. case LINEADDRESSSTATE_INUSEMANY:
  4968. case LINEADDRESSSTATE_NUMCALLS:
  4969. case LINEADDRESSSTATE_TERMINALS:
  4970. LOG((TL_WARN, "HandleAddressStateMessage - not handled %lx", pParams->Param1));
  4971. break;
  4972. default:
  4973. LOG((TL_WARN, "HandleAddressStateMessage - Unknown %lx", pParams->Param1));
  4974. break;
  4975. }
  4976. //FindAddressObject addrefs the address objct
  4977. pAddress->Release();
  4978. return;
  4979. }
  4980. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4981. //
  4982. //
  4983. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4984. void
  4985. CAddress::InService(
  4986. DWORD dwType
  4987. )
  4988. {
  4989. BOOL bEvent = FALSE;
  4990. switch( dwType )
  4991. {
  4992. case LINEDEVSTATE_CONNECTED:
  4993. case LINEDEVSTATE_INSERVICE:
  4994. default:
  4995. break;
  4996. }
  4997. Lock();
  4998. if ( AS_INSERVICE != m_AddressState )
  4999. {
  5000. m_AddressState = AS_INSERVICE;
  5001. bEvent = TRUE;
  5002. }
  5003. Unlock();
  5004. if (bEvent)
  5005. {
  5006. CAddressEvent::FireEvent(
  5007. this,
  5008. AE_STATE,
  5009. NULL
  5010. );
  5011. }
  5012. }
  5013. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5014. //
  5015. //
  5016. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5017. void
  5018. CAddress::OutOfService(
  5019. DWORD dwType
  5020. )
  5021. {
  5022. BOOL bEvent = FALSE;
  5023. switch ( dwType )
  5024. {
  5025. case LINEDEVSTATE_OUTOFSERVICE:
  5026. case LINEDEVSTATE_MAINTENANCE:
  5027. case LINEDEVSTATE_REMOVED:
  5028. case LINEDEVSTATE_DISCONNECTED:
  5029. case LINEDEVSTATE_LOCK:
  5030. default:
  5031. break;
  5032. }
  5033. Lock();
  5034. if ( AS_OUTOFSERVICE != m_AddressState )
  5035. {
  5036. m_AddressState = AS_OUTOFSERVICE;
  5037. bEvent = TRUE;
  5038. }
  5039. Unlock();
  5040. if ( bEvent )
  5041. {
  5042. CAddressEvent::FireEvent(
  5043. this,
  5044. AE_STATE,
  5045. NULL
  5046. );
  5047. }
  5048. }
  5049. void
  5050. CAddress::CapsChange( BOOL bAddress )
  5051. {
  5052. Lock();
  5053. if (bAddress)
  5054. {
  5055. m_dwAddressFlags |= ADDRESSFLAG_ADDRESSCAPSCHANGE;
  5056. }
  5057. else
  5058. {
  5059. m_dwAddressFlags |= ADDRESSFLAG_DEVCAPSCHANGE;
  5060. }
  5061. Unlock();
  5062. CAddressEvent::FireEvent(
  5063. this,
  5064. AE_CAPSCHANGE,
  5065. NULL
  5066. );
  5067. }
  5068. //
  5069. // CAddressEvent
  5070. //
  5071. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5072. //
  5073. //
  5074. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5075. HRESULT
  5076. CAddressEvent::FireEvent(
  5077. CAddress * pCAddress,
  5078. ADDRESS_EVENT Event,
  5079. ITTerminal * pTerminal
  5080. )
  5081. {
  5082. HRESULT hr = S_OK;
  5083. CComObject<CAddressEvent> * p;
  5084. IDispatch * pDisp;
  5085. //
  5086. // Check the event filter mask
  5087. // just if is the AE_NEWTERMINAL or AE_REMOVETERMINAL
  5088. // These two events are MSP events and are not filtered by
  5089. // TapiSrv
  5090. //
  5091. DWORD dwEventFilterMask = 0;
  5092. dwEventFilterMask = pCAddress->GetSubEventsMask( TE_ADDRESS );
  5093. if( !( dwEventFilterMask & GET_SUBEVENT_FLAG(Event)))
  5094. {
  5095. STATICLOG((TL_ERROR, "This event is filtered - %lx", Event));
  5096. return S_OK;
  5097. }
  5098. //
  5099. // create event
  5100. //
  5101. hr = CComObject<CAddressEvent>::CreateInstance( &p );
  5102. if ( !SUCCEEDED(hr) )
  5103. {
  5104. STATICLOG((TL_ERROR, "Could not create AddressEvent object - %lx", hr));
  5105. return hr;
  5106. }
  5107. //
  5108. // initialize
  5109. //
  5110. p->m_Event = Event;
  5111. p->m_pAddress = dynamic_cast<ITAddress *>(pCAddress);
  5112. p->m_pAddress->AddRef();
  5113. p->m_pTerminal = pTerminal;
  5114. if ( NULL != pTerminal )
  5115. {
  5116. pTerminal->AddRef();
  5117. }
  5118. #if DBG
  5119. p->m_pDebug = (PWSTR) ClientAlloc( 1 );
  5120. #endif
  5121. //
  5122. // get idisp interface
  5123. //
  5124. hr = p->QueryInterface(
  5125. IID_IDispatch,
  5126. (void **)&pDisp
  5127. );
  5128. if ( !SUCCEEDED(hr) )
  5129. {
  5130. STATICLOG((TL_ERROR, "Could not get disp interface of AddressEvent object %lx", hr));
  5131. delete p;
  5132. return hr;
  5133. }
  5134. //
  5135. // get callback
  5136. //
  5137. //
  5138. // fire event
  5139. //
  5140. (pCAddress->GetTapi())->Event(
  5141. TE_ADDRESS,
  5142. pDisp
  5143. );
  5144. //
  5145. // release stuff
  5146. //
  5147. pDisp->Release();
  5148. return S_OK;
  5149. }
  5150. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5151. //
  5152. // finalrelease
  5153. //
  5154. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5155. void
  5156. CAddressEvent::FinalRelease()
  5157. {
  5158. LOG((TL_INFO, "CAddressEvent - FinalRelease"));
  5159. m_pAddress->Release();
  5160. if ( NULL != m_pTerminal )
  5161. {
  5162. m_pTerminal->Release();
  5163. }
  5164. #if DBG
  5165. ClientFree( m_pDebug );
  5166. #endif
  5167. }
  5168. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5169. //
  5170. // get_Address
  5171. //
  5172. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5173. STDMETHODIMP
  5174. CAddressEvent::get_Address(
  5175. ITAddress ** ppAddress
  5176. )
  5177. {
  5178. if (TAPIIsBadWritePtr(ppAddress , sizeof(ITAddress *) ) )
  5179. {
  5180. LOG((TL_ERROR, "get_Address - bad pointer"));
  5181. return E_POINTER;
  5182. }
  5183. *ppAddress = m_pAddress;
  5184. (*ppAddress)->AddRef();
  5185. return S_OK;
  5186. }
  5187. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5188. //
  5189. // get_Terminal
  5190. //
  5191. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5192. STDMETHODIMP
  5193. CAddressEvent::get_Terminal(
  5194. ITTerminal ** ppTerminal
  5195. )
  5196. {
  5197. if ( TAPIIsBadWritePtr( ppTerminal , sizeof(ITTerminal *) ) )
  5198. {
  5199. LOG((TL_ERROR, "get_Terminal - bad pointer"));
  5200. return E_POINTER;
  5201. }
  5202. if ((m_Event != AE_NEWTERMINAL) && (m_Event != AE_REMOVETERMINAL))
  5203. {
  5204. LOG((TL_ERROR, "get_Terminal - wrong event"));
  5205. return TAPI_E_WRONGEVENT;
  5206. }
  5207. *ppTerminal = m_pTerminal;
  5208. if ( NULL != m_pTerminal )
  5209. {
  5210. m_pTerminal->AddRef();
  5211. }
  5212. return S_OK;
  5213. }
  5214. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5215. //
  5216. // get_Event
  5217. //
  5218. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5219. STDMETHODIMP
  5220. CAddressEvent::get_Event(
  5221. ADDRESS_EVENT * pEvent
  5222. )
  5223. {
  5224. if (TAPIIsBadWritePtr(pEvent , sizeof(ADDRESS_EVENT) ) )
  5225. {
  5226. LOG((TL_ERROR, "get_Event - bad pointer"));
  5227. return E_POINTER;
  5228. }
  5229. *pEvent = m_Event;
  5230. return S_OK;
  5231. }
  5232. ///////////////////////////////////////////////////////////////////////////////
  5233. //
  5234. // CAddressDevSpecificEvent
  5235. //
  5236. // static
  5237. HRESULT CAddressDevSpecificEvent::FireEvent( CAddress * pCAddress,
  5238. CCall * pCall,
  5239. long l1,
  5240. long l2,
  5241. long l3
  5242. )
  5243. {
  5244. STATICLOG((TL_INFO, "CAddressDevSpecificEvent::FireEvent - enter"));
  5245. //
  5246. // try to create the event
  5247. //
  5248. CComObject<CAddressDevSpecificEvent> *pEventObject = NULL;
  5249. HRESULT hr = CComObject<CAddressDevSpecificEvent>::CreateInstance(&pEventObject);
  5250. if ( FAILED(hr) )
  5251. {
  5252. STATICLOG((TL_ERROR,
  5253. "CAddressDevSpecificEvent::FireEvent - failed to create CAddressDevSpecificEvent. hr = %lx",
  5254. hr));
  5255. return hr;
  5256. }
  5257. //
  5258. // initialize the event with the data we received
  5259. //
  5260. //
  5261. // get ITAddress from CAddress we received
  5262. //
  5263. hr = pCAddress->_InternalQueryInterface(IID_ITAddress, (void**)(&(pEventObject->m_pAddress)) );
  5264. if (FAILED(hr))
  5265. {
  5266. STATICLOG((TL_ERROR,
  5267. "CAddressDevSpecificEvent::FireEvent - failed to create get ITAddress interface from address. hr = %lx",
  5268. hr));
  5269. delete pEventObject;
  5270. return hr;
  5271. }
  5272. //
  5273. // get ITCallInfo interface from CCall we received
  5274. //
  5275. if (NULL != pCall)
  5276. {
  5277. hr = pCall->_InternalQueryInterface(IID_ITCallInfo, (void**)(&(pEventObject->m_pCall)) );
  5278. if (FAILED(hr))
  5279. {
  5280. STATICLOG((TL_ERROR,
  5281. "CAddressDevSpecificEvent::FireEvent - failed to create get ITAddress interface from address. hr = %lx",
  5282. hr));
  5283. //
  5284. // no need to release event's data members, event's destructor will do
  5285. // this for us
  5286. //
  5287. delete pEventObject;
  5288. return hr;
  5289. }
  5290. }
  5291. //
  5292. // keep the actual data
  5293. //
  5294. pEventObject->m_l1 = l1;
  5295. pEventObject->m_l2 = l2;
  5296. pEventObject->m_l3 = l3;
  5297. #if DBG
  5298. pEventObject->m_pDebug = (PWSTR) ClientAlloc( 1 );
  5299. #endif
  5300. //
  5301. // get event's idispatch interface
  5302. //
  5303. IDispatch *pDispatch = NULL;
  5304. hr = pEventObject->QueryInterface( IID_IDispatch,
  5305. (void **)&pDispatch );
  5306. if ( FAILED(hr) )
  5307. {
  5308. STATICLOG((TL_ERROR,
  5309. "CAddressDevSpecificEvent::FireEvent - Could not get disp interface of AddressEvent object %lx",
  5310. hr));
  5311. //
  5312. // no need to release event's data members, event's destructor will do
  5313. // this for us
  5314. //
  5315. //
  5316. // delete the event object
  5317. //
  5318. delete pEventObject;
  5319. return hr;
  5320. }
  5321. //
  5322. // from this point on, we will be using events pDispatch
  5323. //
  5324. pEventObject = NULL;
  5325. //
  5326. // get callback
  5327. //
  5328. //
  5329. // fire event to tapi
  5330. //
  5331. hr = (pCAddress->GetTapi())->Event(TE_ADDRESSDEVSPECIFIC, pDispatch);
  5332. //
  5333. // succeeded or not, we no longer need a reference to the event object
  5334. //
  5335. pDispatch->Release();
  5336. pDispatch = NULL;
  5337. STATICLOG((TL_INFO, "CAddressDevSpecificEvent::FireEvent - exit, hr = %lx", hr));
  5338. return hr;
  5339. }
  5340. ///////////////////////////////////////////////////////////////////////////////
  5341. CAddressDevSpecificEvent::CAddressDevSpecificEvent()
  5342. :m_pAddress(NULL),
  5343. m_pCall(NULL)
  5344. {
  5345. LOG((TL_INFO, "CAddressDevSpecificEvent - enter"));
  5346. #if DBG
  5347. m_pDebug = NULL;
  5348. #endif
  5349. LOG((TL_INFO, "CAddressDevSpecificEvent - exit"));
  5350. }
  5351. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5352. //
  5353. // ~CAddressDevSpecificEvent
  5354. //
  5355. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5356. CAddressDevSpecificEvent::~CAddressDevSpecificEvent()
  5357. {
  5358. LOG((TL_INFO, "~CAddressDevSpecificEvent - enter"));
  5359. if (NULL != m_pAddress)
  5360. {
  5361. m_pAddress->Release();
  5362. m_pAddress = NULL;
  5363. }
  5364. if (NULL != m_pCall)
  5365. {
  5366. m_pCall->Release();
  5367. m_pCall = NULL;
  5368. }
  5369. #if DBG
  5370. ClientFree( m_pDebug );
  5371. #endif
  5372. LOG((TL_INFO, "~CAddressDevSpecificEvent - exit"));
  5373. }
  5374. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5375. //
  5376. // get_Address
  5377. //
  5378. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5379. STDMETHODIMP
  5380. CAddressDevSpecificEvent::get_Address(
  5381. ITAddress ** ppAddress
  5382. )
  5383. {
  5384. LOG((TL_TRACE, "get_Address - enter"));
  5385. //
  5386. // good out pointer?
  5387. //
  5388. if (TAPIIsBadWritePtr(ppAddress , sizeof(ITAddress *) ) )
  5389. {
  5390. LOG((TL_ERROR, "get_Address - bad pointer at [%p]", ppAddress));
  5391. return E_POINTER;
  5392. }
  5393. //
  5394. // return addreff'd address
  5395. //
  5396. _ASSERTE(NULL != m_pAddress);
  5397. *ppAddress = m_pAddress;
  5398. (*ppAddress)->AddRef();
  5399. LOG((TL_TRACE, "get_Address - enter. address[%p]", (*ppAddress) ));
  5400. return S_OK;
  5401. }
  5402. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5403. //
  5404. // get_Address
  5405. //
  5406. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5407. STDMETHODIMP
  5408. CAddressDevSpecificEvent::get_Call(
  5409. ITCallInfo ** ppCall
  5410. )
  5411. {
  5412. LOG((TL_TRACE, "get_Call - enter"));
  5413. //
  5414. // good out pointer?
  5415. //
  5416. if (TAPIIsBadWritePtr(ppCall, sizeof(ITCallInfo*) ) )
  5417. {
  5418. LOG((TL_ERROR, "get_Call - bad pointer at [%p]", ppCall));
  5419. return E_POINTER;
  5420. }
  5421. //
  5422. // return addreff'd call
  5423. //
  5424. HRESULT hr = S_OK;
  5425. if ( NULL != m_pCall )
  5426. {
  5427. //
  5428. // this event is call specific
  5429. //
  5430. *ppCall = m_pCall;
  5431. (*ppCall)->AddRef();
  5432. }
  5433. else
  5434. {
  5435. //
  5436. // this event was not call specific
  5437. //
  5438. LOG((TL_WARN, "get_Call - no call"));
  5439. hr = TAPI_E_CALLUNAVAIL;
  5440. }
  5441. LOG(( TL_TRACE, "get_Call - enter. call [%p]. hr = %lx", (*ppCall), hr ));
  5442. return hr;
  5443. }
  5444. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5445. //
  5446. // get_lParam1
  5447. //
  5448. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5449. STDMETHODIMP CAddressDevSpecificEvent::get_lParam1( long *pl1 )
  5450. {
  5451. LOG((TL_TRACE, "get_lParam1 - enter"));
  5452. //
  5453. // good out pointer?
  5454. //
  5455. if (TAPIIsBadWritePtr(pl1, sizeof(long) ) )
  5456. {
  5457. LOG((TL_ERROR, "get_lParam1 - bad pointer at %p", pl1));
  5458. return E_POINTER;
  5459. }
  5460. //
  5461. // log and return the value
  5462. //
  5463. *pl1 = m_l1;
  5464. LOG((TL_TRACE, "get_lParam1 - exit. p1[%ld]", *pl1));
  5465. return S_OK;
  5466. }
  5467. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5468. //
  5469. // get_lParam2
  5470. //
  5471. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5472. STDMETHODIMP CAddressDevSpecificEvent::get_lParam2( long *pl2 )
  5473. {
  5474. LOG((TL_TRACE, "get_lParam2 - enter"));
  5475. //
  5476. // good out pointer?
  5477. //
  5478. if (TAPIIsBadWritePtr(pl2, sizeof(long) ) )
  5479. {
  5480. LOG((TL_ERROR, "get_lParam2 - bad pointer at %p", pl2));
  5481. return E_POINTER;
  5482. }
  5483. //
  5484. // log and return the value
  5485. //
  5486. *pl2 = m_l2;
  5487. LOG((TL_TRACE, "get_lParam2 - exit. p2[%ld]", *pl2));
  5488. return S_OK;
  5489. }
  5490. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5491. //
  5492. // get_lParam3
  5493. //
  5494. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5495. STDMETHODIMP CAddressDevSpecificEvent::get_lParam3( long *pl3 )
  5496. {
  5497. LOG((TL_TRACE, "get_lParam3 - enter"));
  5498. //
  5499. // good out pointer?
  5500. //
  5501. if ( TAPIIsBadWritePtr(pl3, sizeof(long)) )
  5502. {
  5503. LOG((TL_ERROR, "get_lParam3 - bad pointer at %p", pl3));
  5504. return E_POINTER;
  5505. }
  5506. //
  5507. // log and return the value
  5508. //
  5509. *pl3 = m_l3;
  5510. LOG((TL_TRACE, "get_lParam3 - exit. p3[%ld]", *pl3));
  5511. return S_OK;
  5512. }
  5513. ///////////////////////////////////////////////////////////////////////////////
  5514. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5515. //
  5516. // Initialize
  5517. //
  5518. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5519. HRESULT
  5520. CForwardInfo::Initialize()
  5521. {
  5522. HRESULT hr = S_OK;
  5523. ZeroMemory(
  5524. m_ForwardStructs,
  5525. sizeof( MYFORWARDSTRUCT ) * NUMFORWARDTYPES
  5526. );
  5527. m_lNumRings = 0;
  5528. return hr;
  5529. }
  5530. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5531. //
  5532. // GetForwardOffset
  5533. //
  5534. // maps a forward type to an offset for the array
  5535. // in the
  5536. //
  5537. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5538. DWORD
  5539. GetForwardOffset(
  5540. DWORD dwForwardType
  5541. )
  5542. {
  5543. switch (dwForwardType)
  5544. {
  5545. case LINEFORWARDMODE_UNCOND:
  5546. return 0;
  5547. case LINEFORWARDMODE_UNCONDINTERNAL:
  5548. return 1;
  5549. case LINEFORWARDMODE_UNCONDEXTERNAL:
  5550. return 2;
  5551. case LINEFORWARDMODE_UNCONDSPECIFIC:
  5552. return 3;
  5553. case LINEFORWARDMODE_BUSY:
  5554. return 4;
  5555. case LINEFORWARDMODE_BUSYINTERNAL:
  5556. return 5;
  5557. case LINEFORWARDMODE_BUSYEXTERNAL:
  5558. return 6;
  5559. case LINEFORWARDMODE_BUSYSPECIFIC:
  5560. return 7;
  5561. case LINEFORWARDMODE_NOANSW:
  5562. return 8;
  5563. case LINEFORWARDMODE_NOANSWINTERNAL:
  5564. return 9;
  5565. case LINEFORWARDMODE_NOANSWEXTERNAL:
  5566. return 10;
  5567. case LINEFORWARDMODE_NOANSWSPECIFIC:
  5568. return 11;
  5569. case LINEFORWARDMODE_BUSYNA:
  5570. return 12;
  5571. case LINEFORWARDMODE_BUSYNAINTERNAL:
  5572. return 13;
  5573. case LINEFORWARDMODE_BUSYNAEXTERNAL:
  5574. return 14;
  5575. case LINEFORWARDMODE_BUSYNASPECIFIC:
  5576. return 15;
  5577. case LINEFORWARDMODE_UNKNOWN:
  5578. return 16;
  5579. case LINEFORWARDMODE_UNAVAIL:
  5580. return 17;
  5581. default:
  5582. return 0;
  5583. }
  5584. return 0;
  5585. }
  5586. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5587. //
  5588. // put_NumRingsNoAnswer
  5589. //
  5590. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5591. STDMETHODIMP
  5592. CForwardInfo::put_NumRingsNoAnswer(
  5593. long lNumRings
  5594. )
  5595. {
  5596. HRESULT hr = S_OK;
  5597. Lock();
  5598. m_lNumRings = lNumRings;
  5599. Unlock();
  5600. return hr;
  5601. }
  5602. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5603. //
  5604. // get_NumRingsNoAnswer
  5605. //
  5606. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5607. STDMETHODIMP
  5608. CForwardInfo::get_NumRingsNoAnswer(
  5609. long * plNumRings
  5610. )
  5611. {
  5612. if (TAPIIsBadWritePtr(plNumRings , sizeof(long) ) )
  5613. {
  5614. LOG((TL_ERROR, "get_NumRingsNoAnswer - bad pointer"));
  5615. return E_POINTER;
  5616. }
  5617. Lock();
  5618. *plNumRings = m_lNumRings;
  5619. Unlock();
  5620. return S_OK;
  5621. }
  5622. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5623. //
  5624. // SetForwardType
  5625. //
  5626. // save the forward type. overwrite and free is there is already
  5627. // a matching type
  5628. //
  5629. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5630. STDMETHODIMP
  5631. CForwardInfo::SetForwardType(
  5632. long ForwardType,
  5633. BSTR pDestAddress,
  5634. BSTR pCallerAddress
  5635. )
  5636. {
  5637. HRESULT hr;
  5638. LOG((TL_TRACE, "SetForwardType - enter"));
  5639. hr = SetForwardType2(
  5640. ForwardType,
  5641. pDestAddress,
  5642. 0,
  5643. pCallerAddress,
  5644. 0
  5645. );
  5646. LOG((TL_TRACE, "SetForwardType - exit - %lx", hr));
  5647. return hr;
  5648. }
  5649. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5650. //
  5651. // SetForwardType2
  5652. //
  5653. // save the forward type. overwrite and free is there is already
  5654. // a matching type
  5655. //
  5656. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5657. STDMETHODIMP
  5658. CForwardInfo::SetForwardType2(
  5659. long ForwardType,
  5660. BSTR pDestAddress,
  5661. long DestAddressType,
  5662. BSTR pCallerAddress,
  5663. long CallerAddressType
  5664. )
  5665. {
  5666. HRESULT hr = S_OK;
  5667. DWORD dwCount;
  5668. LOG((TL_TRACE, "SetForwardType2 - enter"));
  5669. //
  5670. // check forwardtype
  5671. //
  5672. if ( !IsOnlyOneBitSetInDWORD( ForwardType ) )
  5673. {
  5674. LOG((TL_ERROR, "ForwardType has more than one bit set"));
  5675. return E_INVALIDARG;
  5676. }
  5677. //
  5678. // check destaddress
  5679. //
  5680. if ( pDestAddress == NULL )
  5681. {
  5682. LOG((TL_ERROR, "Forward destaddress cannot be NULL"));
  5683. return E_INVALIDARG;
  5684. }
  5685. if ( IsBadStringPtrW( pDestAddress, -1 ) )
  5686. {
  5687. LOG((TL_ERROR, "Forward destaddress invalid"));
  5688. return E_POINTER;
  5689. }
  5690. //
  5691. // check calleraddress
  5692. //
  5693. if ( FORWARDMODENEEDSCALLER( ForwardType ) )
  5694. {
  5695. if ( NULL == pCallerAddress )
  5696. {
  5697. LOG((TL_ERROR, "Forward type needs calleraddress"));
  5698. return E_INVALIDARG;
  5699. }
  5700. if ( IsBadStringPtrW( pCallerAddress, -1 ) )
  5701. {
  5702. LOG((TL_ERROR, "Forward calleraddress invalid"));
  5703. return E_POINTER;
  5704. }
  5705. }
  5706. Lock();
  5707. //
  5708. // find correct structure in array
  5709. //
  5710. MYFORWARDSTRUCT * pStruct = NULL;
  5711. pStruct = &(m_ForwardStructs[GetForwardOffset(ForwardType)]);
  5712. //
  5713. // free alloced stuff
  5714. //
  5715. if ( NULL != pStruct->bstrDestination )
  5716. {
  5717. SysFreeString( pStruct->bstrDestination );
  5718. pStruct->bstrDestination = NULL;
  5719. }
  5720. if ( NULL != pStruct->bstrCaller )
  5721. {
  5722. SysFreeString( pStruct->bstrCaller );
  5723. pStruct->bstrCaller = NULL;
  5724. }
  5725. //
  5726. // save stuff
  5727. //
  5728. pStruct->bstrDestination = SysAllocString( pDestAddress );
  5729. if ( NULL == pStruct->bstrDestination )
  5730. {
  5731. Unlock();
  5732. LOG((TL_ERROR, "Could not alloc dest in put_Forward"));
  5733. return E_OUTOFMEMORY;
  5734. }
  5735. if ( NULL != pCallerAddress )
  5736. {
  5737. pStruct->bstrCaller = SysAllocString( pCallerAddress );
  5738. if ( NULL == pStruct->bstrCaller )
  5739. {
  5740. LOG((TL_ERROR, "Could not calloc caller in put_Forward"));
  5741. SysFreeString( pStruct->bstrDestination );
  5742. Unlock();
  5743. return E_OUTOFMEMORY;
  5744. }
  5745. }
  5746. pStruct->dwDestAddressType = DestAddressType;
  5747. pStruct->dwCallerAddressType = CallerAddressType;
  5748. pStruct->dwForwardType = ForwardType;
  5749. Unlock();
  5750. LOG((TL_TRACE, "SetForwardType2 - exit - success"));
  5751. return S_OK;
  5752. }
  5753. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5754. //
  5755. // get_ForwardTypeDestination
  5756. //
  5757. // will return null if nothing saved
  5758. //
  5759. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5760. STDMETHODIMP
  5761. CForwardInfo::get_ForwardTypeDestination(
  5762. long ForwardType,
  5763. BSTR * ppDestAddress
  5764. )
  5765. {
  5766. HRESULT hr = S_OK;
  5767. DWORD dwCount;
  5768. LOG((TL_TRACE, "get_ForwardTypeDest - enter"));
  5769. //
  5770. // check forwardtype
  5771. //
  5772. if ( !IsOnlyOneBitSetInDWORD( ForwardType ) )
  5773. {
  5774. LOG((TL_ERROR, "ForwardType has more than one bit set"));
  5775. return E_INVALIDARG;
  5776. }
  5777. if ( TAPIIsBadWritePtr( ppDestAddress, sizeof( BSTR ) ) )
  5778. {
  5779. LOG((TL_ERROR, "Bad pointer in get_ForwardTypeDest"));
  5780. return E_POINTER;
  5781. }
  5782. *ppDestAddress = NULL;
  5783. Lock();
  5784. dwCount = GetForwardOffset( ForwardType );
  5785. if ( NULL != m_ForwardStructs[dwCount].bstrDestination )
  5786. {
  5787. *ppDestAddress = SysAllocString(
  5788. m_ForwardStructs[dwCount].bstrDestination
  5789. );
  5790. if ( NULL == *ppDestAddress )
  5791. {
  5792. LOG((TL_ERROR, "OutOfMemory in get_ForwardTypeDest"));
  5793. Unlock();
  5794. return E_POINTER;
  5795. }
  5796. }
  5797. Unlock();
  5798. LOG((TL_TRACE, "get_ForwardTypeDest - exit"));
  5799. return S_OK;
  5800. }
  5801. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5802. //
  5803. // get_ForwardTypeDestinationAddressType
  5804. //
  5805. // will return null if nothing saved
  5806. //
  5807. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5808. STDMETHODIMP
  5809. CForwardInfo::get_ForwardTypeDestinationAddressType(
  5810. long ForwardType,
  5811. long * pDestAddressType
  5812. )
  5813. {
  5814. HRESULT hr = S_OK;
  5815. DWORD dwCount;
  5816. LOG((TL_TRACE, "get_ForwardTypeDestinationAddressType - enter"));
  5817. //
  5818. // check forwardtype
  5819. //
  5820. if ( !IsOnlyOneBitSetInDWORD( ForwardType ) )
  5821. {
  5822. LOG((TL_ERROR, "ForwardType has more than one bit set"));
  5823. return E_INVALIDARG;
  5824. }
  5825. if ( TAPIIsBadWritePtr( pDestAddressType, sizeof( long ) ) )
  5826. {
  5827. LOG((TL_ERROR, "Bad pointer in get_ForwardTypeDestinationAddressType"));
  5828. return E_POINTER;
  5829. }
  5830. Lock();
  5831. dwCount = GetForwardOffset( ForwardType );
  5832. *pDestAddressType = m_ForwardStructs[dwCount].dwDestAddressType;
  5833. Unlock();
  5834. LOG((TL_TRACE, "get_ForwardTypeDestinationAddressType - exit"));
  5835. return S_OK;
  5836. }
  5837. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5838. //
  5839. // get_ForwardTypeCaller
  5840. //
  5841. // gets the caller save for the specifies forward type
  5842. //
  5843. // will return NULL in ppCallerAddress if nothing saved
  5844. //
  5845. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5846. STDMETHODIMP
  5847. CForwardInfo::get_ForwardTypeCaller(
  5848. long ForwardType,
  5849. BSTR * ppCallerAddress
  5850. )
  5851. {
  5852. HRESULT hr = S_OK;
  5853. DWORD dwCount;
  5854. LOG((TL_TRACE, "get_ForwardTypeCaller - enter"));
  5855. //
  5856. // check forwardtype
  5857. //
  5858. if ( !IsOnlyOneBitSetInDWORD( ForwardType ) )
  5859. {
  5860. LOG((TL_ERROR, "ForwardType has more than one bit set"));
  5861. return E_INVALIDARG;
  5862. }
  5863. if ( TAPIIsBadWritePtr( ppCallerAddress, sizeof( BSTR ) ) )
  5864. {
  5865. LOG((TL_ERROR, "Bad pointer in get_ForwardTypeCaller"));
  5866. return E_POINTER;
  5867. }
  5868. *ppCallerAddress = NULL;
  5869. Lock();
  5870. dwCount = GetForwardOffset( ForwardType );
  5871. if ( NULL != m_ForwardStructs[dwCount].bstrCaller )
  5872. {
  5873. *ppCallerAddress = SysAllocString(
  5874. m_ForwardStructs[dwCount].bstrCaller
  5875. );
  5876. if ( NULL == *ppCallerAddress )
  5877. {
  5878. LOG((TL_ERROR, "OutOfMemory in get_ForwardTypeCaller"));
  5879. Unlock();
  5880. return E_POINTER;
  5881. }
  5882. }
  5883. Unlock();
  5884. LOG((TL_TRACE, "get_ForwardTypeDest - exit"));
  5885. return S_OK;
  5886. }
  5887. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5888. //
  5889. // get_ForwardTypeCallerAddressType
  5890. //
  5891. // will return null if nothing saved
  5892. //
  5893. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5894. STDMETHODIMP
  5895. CForwardInfo::get_ForwardTypeCallerAddressType(
  5896. long ForwardType,
  5897. long * pCallerAddressType
  5898. )
  5899. {
  5900. HRESULT hr = S_OK;
  5901. DWORD dwCount;
  5902. LOG((TL_TRACE, "get_ForwardTypeCallerAddressType - enter"));
  5903. //
  5904. // check forwardtype
  5905. //
  5906. if ( !IsOnlyOneBitSetInDWORD( ForwardType ) )
  5907. {
  5908. LOG((TL_ERROR, "ForwardType has more than one bit set"));
  5909. return E_INVALIDARG;
  5910. }
  5911. if ( TAPIIsBadWritePtr( pCallerAddressType, sizeof( long ) ) )
  5912. {
  5913. LOG((TL_ERROR, "Bad pointer in get_ForwardTypeCallerAddressType"));
  5914. return E_POINTER;
  5915. }
  5916. Lock();
  5917. dwCount = GetForwardOffset( ForwardType );
  5918. *pCallerAddressType = m_ForwardStructs[dwCount].dwCallerAddressType;
  5919. Unlock();
  5920. LOG((TL_TRACE, "get_ForwardTypeCallerAddressType - exit"));
  5921. return S_OK;
  5922. }
  5923. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5924. //
  5925. // GetForwardType
  5926. //
  5927. // get the destination and caller based on the type
  5928. //
  5929. // simply use the vb functions to do this.
  5930. //
  5931. // will return success even if no info - both addresses will
  5932. // be NULL in that case
  5933. //
  5934. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5935. STDMETHODIMP
  5936. CForwardInfo::GetForwardType(
  5937. long ForwardType,
  5938. BSTR * ppDestinationAddress,
  5939. BSTR * ppCallerAddress
  5940. )
  5941. {
  5942. HRESULT hr = S_OK;
  5943. LOG((TL_TRACE, "GetForwardType - enter"));
  5944. hr = get_ForwardTypeDestination( ForwardType, ppDestinationAddress );
  5945. if ( !SUCCEEDED(hr) )
  5946. {
  5947. return hr;
  5948. }
  5949. hr = get_ForwardTypeCaller( ForwardType, ppCallerAddress );
  5950. if ( !SUCCEEDED(hr) )
  5951. {
  5952. SysFreeString( *ppDestinationAddress );
  5953. return hr;
  5954. }
  5955. LOG((TL_TRACE, "GetForwardType - exit"));
  5956. return hr;
  5957. }
  5958. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5959. //
  5960. // GetForwardType2
  5961. //
  5962. // get the destination and caller based on the type
  5963. //
  5964. // simply use the vb functions to do this.
  5965. //
  5966. // will return success even if no info - both addresses will
  5967. // be NULL in that case
  5968. //
  5969. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5970. STDMETHODIMP
  5971. CForwardInfo::GetForwardType2(
  5972. long ForwardType,
  5973. BSTR * ppDestinationAddress,
  5974. long * pDestAddressType,
  5975. BSTR * ppCallerAddress,
  5976. long * pCallerAddressType
  5977. )
  5978. {
  5979. HRESULT hr = S_OK;
  5980. LOG((TL_TRACE, "GetForwardType2 - enter"));
  5981. hr = get_ForwardTypeDestination( ForwardType, ppDestinationAddress );
  5982. if ( !SUCCEEDED(hr) )
  5983. {
  5984. return hr;
  5985. }
  5986. hr = get_ForwardTypeDestinationAddressType( ForwardType, pDestAddressType );
  5987. if ( !SUCCEEDED(hr) )
  5988. {
  5989. SysFreeString( *ppDestinationAddress );
  5990. return hr;
  5991. }
  5992. hr = get_ForwardTypeCaller( ForwardType, ppCallerAddress );
  5993. if ( !SUCCEEDED(hr) )
  5994. {
  5995. SysFreeString( *ppDestinationAddress );
  5996. return hr;
  5997. }
  5998. hr = get_ForwardTypeCallerAddressType( ForwardType, pCallerAddressType );
  5999. if ( !SUCCEEDED(hr) )
  6000. {
  6001. SysFreeString( *ppDestinationAddress );
  6002. SysFreeString( *ppCallerAddress );
  6003. return hr;
  6004. }
  6005. LOG((TL_TRACE, "GetForwardType2 - exit"));
  6006. return hr;
  6007. }
  6008. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6009. //
  6010. // Clear
  6011. //
  6012. // clears & frees all info in the forward object
  6013. //
  6014. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6015. STDMETHODIMP
  6016. CForwardInfo::Clear()
  6017. {
  6018. HRESULT hr = S_OK;
  6019. DWORD dwCount;
  6020. LOG((TL_TRACE, "Clear - enter"));
  6021. Lock();
  6022. //
  6023. // go through all the structs and free
  6024. // related memory
  6025. //
  6026. for (dwCount = 0; dwCount < NUMFORWARDTYPES; dwCount++)
  6027. {
  6028. if ( NULL != m_ForwardStructs[dwCount].bstrDestination )
  6029. {
  6030. SysFreeString( m_ForwardStructs[dwCount].bstrDestination );
  6031. }
  6032. if ( NULL != m_ForwardStructs[dwCount].bstrCaller )
  6033. {
  6034. SysFreeString( m_ForwardStructs[dwCount].bstrCaller );
  6035. }
  6036. }
  6037. //
  6038. // zero out stuff
  6039. //
  6040. ZeroMemory(
  6041. m_ForwardStructs,
  6042. sizeof( MYFORWARDSTRUCT ) * NUMFORWARDTYPES
  6043. );
  6044. Unlock();
  6045. LOG((TL_TRACE, "Clear - exit"));
  6046. return S_OK;
  6047. }
  6048. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6049. //
  6050. // CreateForwardList
  6051. //
  6052. // Creates a LINEFORWARDLIST structure based on the info
  6053. // in the object
  6054. //
  6055. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6056. HRESULT
  6057. CForwardInfo::CreateForwardList(
  6058. LINEFORWARDLIST ** ppList
  6059. )
  6060. {
  6061. LINEFORWARDLIST * pList;
  6062. DWORD dwCount;
  6063. DWORD dwSize = 0;
  6064. DWORD dwOffset;
  6065. DWORD dwNumEntries = 0;
  6066. Lock();
  6067. //
  6068. // count the number of entries that are filled
  6069. //
  6070. for (dwCount = 0; dwCount < NUMFORWARDTYPES; dwCount++)
  6071. {
  6072. if ( 0 != m_ForwardStructs[dwCount].dwForwardType )
  6073. {
  6074. dwSize += ( (lstrlenW( m_ForwardStructs[dwCount].bstrDestination ) + 1) * sizeof(WCHAR*));
  6075. dwSize += ( (lstrlenW( m_ForwardStructs[dwCount].bstrCaller ) + 1) * sizeof(WCHAR*));
  6076. dwNumEntries++;
  6077. }
  6078. }
  6079. if ( 0 == dwNumEntries )
  6080. {
  6081. Unlock();
  6082. *ppList = NULL;
  6083. return S_OK;
  6084. }
  6085. dwSize += sizeof (LINEFORWARDLIST) +
  6086. sizeof (LINEFORWARD) * dwNumEntries +
  6087. dwSize;
  6088. //
  6089. // alloc structure
  6090. //
  6091. pList = (LINEFORWARDLIST *)ClientAlloc( dwSize );
  6092. if ( NULL == pList )
  6093. {
  6094. LOG((TL_ERROR, "CreateForwardList - OutOfMemory"));
  6095. Unlock();
  6096. return E_OUTOFMEMORY;
  6097. }
  6098. //
  6099. // init
  6100. //
  6101. pList->dwTotalSize = dwSize;
  6102. pList->dwNumEntries = dwNumEntries;
  6103. //
  6104. // offset should be past the fixed part of the structure
  6105. //
  6106. dwOffset = sizeof( LINEFORWARDLIST ) + sizeof( LINEFORWARD ) * dwNumEntries;
  6107. dwNumEntries = 0;
  6108. //
  6109. // go through entries again
  6110. //
  6111. for (dwCount = 0; dwCount < NUMFORWARDTYPES; dwCount++)
  6112. {
  6113. if ( 0 != m_ForwardStructs[dwCount].dwForwardType )
  6114. {
  6115. DWORD dwSize;
  6116. LINEFORWARD * pEntry = &(pList->ForwardList[dwNumEntries]);
  6117. //
  6118. // save the type
  6119. //
  6120. pEntry->dwForwardMode = m_ForwardStructs[dwCount].dwForwardType;
  6121. //
  6122. // save destination - should always be a destination if
  6123. // there is a type
  6124. //
  6125. pEntry->dwDestAddressType = m_ForwardStructs[dwCount].dwDestAddressType;
  6126. pEntry->dwDestAddressSize = (lstrlenW(m_ForwardStructs[dwCount].bstrDestination) + 1)
  6127. * sizeof( WCHAR );
  6128. pEntry->dwDestAddressOffset = dwOffset;
  6129. lstrcpyW(
  6130. (PWSTR)(((PBYTE)pList)+dwOffset),
  6131. m_ForwardStructs[dwCount].bstrDestination
  6132. );
  6133. //
  6134. // fixup offset
  6135. //
  6136. dwOffset += pEntry->dwDestAddressSize;
  6137. //
  6138. // if there is a caller, do the same
  6139. //
  6140. if ( NULL != m_ForwardStructs[dwCount].bstrCaller )
  6141. {
  6142. pEntry->dwCallerAddressType = m_ForwardStructs[dwCount].dwCallerAddressType;
  6143. pEntry->dwCallerAddressSize = (lstrlenW(m_ForwardStructs[dwCount].bstrCaller) + 1)
  6144. * sizeof( WCHAR );
  6145. pEntry->dwCallerAddressOffset = dwOffset;
  6146. lstrcpyW(
  6147. (PWSTR)(((PBYTE)pList)+dwOffset),
  6148. m_ForwardStructs[dwCount].bstrCaller
  6149. );
  6150. dwOffset += pEntry->dwCallerAddressSize;
  6151. }
  6152. dwNumEntries++;
  6153. }
  6154. }
  6155. //
  6156. // return it
  6157. //
  6158. *ppList = pList;
  6159. Unlock();
  6160. return S_OK;
  6161. }
  6162. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6163. //
  6164. // FinalRelease()
  6165. //
  6166. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6167. void
  6168. CForwardInfo::FinalRelease()
  6169. {
  6170. //
  6171. // simply clear it
  6172. //
  6173. Clear();
  6174. }
  6175. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6176. // Class : CAddress
  6177. // Interface : ITAddressTranslation
  6178. // Method : TranslateAddress
  6179. //
  6180. //
  6181. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6182. STDMETHODIMP
  6183. CAddress::TranslateAddress(
  6184. BSTR pAddressToTranslate,
  6185. long ulCard,
  6186. long ulTranslateOptions,
  6187. ITAddressTranslationInfo ** ppTranslated
  6188. )
  6189. {
  6190. HRESULT hr = S_OK;
  6191. LPLINETRANSLATEOUTPUT pTranslateOutput = NULL;
  6192. PWSTR pszDialableString = NULL;
  6193. PWSTR pszDisplayableString = NULL;
  6194. CComObject< CAddressTranslationInfo > * pTranslationInfo = NULL;
  6195. long lCap = 0;
  6196. BOOL bUsePSTNAddressTranslation = TRUE;
  6197. HLINEAPP hLineApp;
  6198. DWORD dwDeviceID;
  6199. LOG((TL_TRACE, "TranslateAddress - enter" ));
  6200. if ( !TAPIIsBadWritePtr( ppTranslated, sizeof(ITAddressTranslationInfo *) ) )
  6201. {
  6202. // ppTranslated OK
  6203. if ( !IsBadStringPtrW( pAddressToTranslate, -1 ) )
  6204. {
  6205. // pAddressToTranslate OK
  6206. // Check Addresscap bit
  6207. hr = get_AddressCapability( AC_ADDRESSCAPFLAGS, &lCap );
  6208. if ( SUCCEEDED(hr) )
  6209. {
  6210. if ( lCap & LINEADDRCAPFLAGS_NOPSTNADDRESSTRANSLATION )
  6211. {
  6212. bUsePSTNAddressTranslation = FALSE;
  6213. }
  6214. }
  6215. // create Translate Info object
  6216. hr = CComObject< CAddressTranslationInfo >::CreateInstance( &pTranslationInfo );
  6217. if ( SUCCEEDED(hr) )
  6218. {
  6219. // Translate or copy ?
  6220. if (bUsePSTNAddressTranslation)
  6221. {
  6222. LOG((TL_INFO, "TranslateAddress - Do address translation" ));
  6223. Lock();
  6224. hLineApp = m_hLineApp;
  6225. dwDeviceID = m_dwDeviceID;
  6226. Unlock();
  6227. hr= LineTranslateAddress(
  6228. hLineApp,
  6229. dwDeviceID,
  6230. TAPI_CURRENT_VERSION,
  6231. (LPCWSTR)pAddressToTranslate,
  6232. ulCard,
  6233. ulTranslateOptions,
  6234. &pTranslateOutput);
  6235. if(SUCCEEDED(hr) )
  6236. {
  6237. // Pull String info out of LPLINETRANSLATEOUTPUT structure
  6238. pszDialableString = (PWSTR) ((BYTE*)(pTranslateOutput) + pTranslateOutput->dwDialableStringOffset);
  6239. pszDisplayableString = (PWSTR) ((BYTE*)(pTranslateOutput) + pTranslateOutput->dwDisplayableStringOffset);
  6240. hr = pTranslationInfo->Initialize(pszDialableString,
  6241. pszDisplayableString,
  6242. pTranslateOutput->dwCurrentCountry,
  6243. pTranslateOutput->dwDestCountry,
  6244. pTranslateOutput->dwTranslateResults
  6245. );
  6246. }
  6247. else // LinetranslateAddress failed
  6248. {
  6249. LOG((TL_ERROR, "TranslateAddress - LineTranslateAddress failed" ));
  6250. }
  6251. }
  6252. else // copy input string unmodified
  6253. {
  6254. LOG((TL_INFO, "TranslateAddress - No address translation" ));
  6255. hr = pTranslationInfo->Initialize(pAddressToTranslate,
  6256. pAddressToTranslate,
  6257. 0,
  6258. 0,
  6259. LINETRANSLATERESULT_NOTRANSLATION
  6260. );
  6261. } // end if (bUsePSTNAddressTranslation)
  6262. //
  6263. // Did we translate & initialize output object ?
  6264. if ( SUCCEEDED(hr) )
  6265. {
  6266. hr = pTranslationInfo->QueryInterface(IID_ITAddressTranslationInfo,(void**)ppTranslated);
  6267. if ( SUCCEEDED(hr) )
  6268. {
  6269. LOG((TL_TRACE, "TranslateAddress - success"));
  6270. hr = S_OK;
  6271. }
  6272. else
  6273. {
  6274. LOG((TL_ERROR, "TranslateAddress - Bad pointer" ));
  6275. delete pTranslationInfo;
  6276. }
  6277. }
  6278. else // object failed to initialize
  6279. {
  6280. LOG((TL_ERROR, "TranslateAddress - Initialize TranslateInfo object failed" ));
  6281. delete pTranslationInfo;
  6282. }
  6283. }
  6284. else // Create instance failed
  6285. {
  6286. LOG((TL_ERROR, "TranslateAddress - Create TranslateInfo object failed" ));
  6287. }
  6288. }
  6289. else // pAddressToTranslate bad
  6290. {
  6291. LOG((TL_ERROR, "TranslateAddress -pAddressToTranslate invalid"));
  6292. hr = E_POINTER;
  6293. }
  6294. }
  6295. else // ppTranslated bad
  6296. {
  6297. LOG((TL_ERROR, "TranslateAddress - Bad ppTranslated Pointer" ));
  6298. hr = E_POINTER;
  6299. }
  6300. if(pTranslateOutput != NULL)
  6301. {
  6302. ClientFree(pTranslateOutput);
  6303. }
  6304. LOG((TL_TRACE, hr, "TranslateAddress - exit" ));
  6305. return hr;
  6306. }
  6307. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6308. //
  6309. // TranslateDialog
  6310. //
  6311. // simply call LineTranslateDialog
  6312. //
  6313. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6314. STDMETHODIMP
  6315. CAddress::TranslateDialog(
  6316. TAPIHWND hwndOwner,
  6317. BSTR pAddressIn
  6318. )
  6319. {
  6320. HRESULT hr = E_NOTIMPL;
  6321. HLINEAPP hLineApp;
  6322. DWORD dwDeviceID;
  6323. DWORD dwAPIVersion;
  6324. LOG((TL_TRACE, "TranslateDialog - enter:%p", hwndOwner ));
  6325. Lock();
  6326. hLineApp = m_hLineApp;
  6327. dwDeviceID = m_dwDeviceID;
  6328. dwAPIVersion = m_dwAPIVersion;
  6329. Unlock();
  6330. hr = LineTranslateDialog(
  6331. dwDeviceID,
  6332. dwAPIVersion,
  6333. (HWND)hwndOwner,
  6334. pAddressIn
  6335. );
  6336. LOG((TL_TRACE, "TranslateDialog - exit - return %lx", hr));
  6337. return hr;
  6338. }
  6339. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6340. // Class : CAddress
  6341. // Interface : ITAddressTranslation
  6342. // Method : EnumerateLocations
  6343. //
  6344. //
  6345. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6346. STDMETHODIMP CAddress::EnumerateLocations (IEnumLocation ** ppEnumLocation )
  6347. {
  6348. HRESULT hr = S_OK;
  6349. LPLINETRANSLATECAPS pTranslateCaps = NULL;
  6350. DWORD dwNumLocations;
  6351. DWORD dwCount;
  6352. LPLINELOCATIONENTRY pEntry = NULL;
  6353. PWSTR pszLocationName;
  6354. PWSTR pszCityCode;
  6355. PWSTR pszLocalAccessCode;
  6356. PWSTR pszLongDistanceAccessCode;
  6357. PWSTR pszTollPrefixList;
  6358. PWSTR pszCancelCallWaitingCode;
  6359. DWORD dwPermanentLocationID;
  6360. DWORD dwCountryCode;
  6361. DWORD dwPreferredCardID;
  6362. DWORD dwCountryID;
  6363. DWORD dwOptions;
  6364. LOG((TL_TRACE, "EnumerateLocations - enter" ));
  6365. if ( TAPIIsBadWritePtr( ppEnumLocation, sizeof(IEnumLocation *) ) )
  6366. {
  6367. LOG((TL_ERROR, "EnumerateLocations - Bad Pointer" ));
  6368. hr = E_POINTER;
  6369. }
  6370. else // Ok Pointer
  6371. {
  6372. //
  6373. // create the enumerator
  6374. //
  6375. CComObject< CTapiEnum<IEnumLocation, ITLocationInfo, &IID_IEnumLocation> > * pEnum;
  6376. hr = CComObject< CTapiEnum<IEnumLocation, ITLocationInfo, &IID_IEnumLocation> > ::CreateInstance( &pEnum );
  6377. if (SUCCEEDED(hr) )
  6378. {
  6379. //
  6380. // initialize it with our Locations list
  6381. //
  6382. pEnum->Initialize();
  6383. hr = LineGetTranslateCaps(m_hLineApp, TAPI_CURRENT_VERSION, &pTranslateCaps);
  6384. if(SUCCEEDED(hr) )
  6385. {
  6386. dwNumLocations = pTranslateCaps->dwNumLocations ;
  6387. // Find positionn of 1st LINELOCATIONENTRY structure in the LINETRANSLATECAPS structure
  6388. pEntry = (LPLINELOCATIONENTRY) ((BYTE*)(pTranslateCaps) + pTranslateCaps->dwLocationListOffset );
  6389. for (dwCount = 0; dwCount < dwNumLocations; dwCount++)
  6390. {
  6391. // Pull Location Info out of LINELOCATIONENTRY structure
  6392. pszLocationName = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwLocationNameOffset);
  6393. pszCityCode = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwCityCodeOffset);
  6394. pszLocalAccessCode = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwLocalAccessCodeOffset);
  6395. pszLongDistanceAccessCode = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwLongDistanceAccessCodeOffset);
  6396. pszTollPrefixList = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwTollPrefixListOffset);
  6397. pszCancelCallWaitingCode = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwCancelCallWaitingOffset);
  6398. dwPermanentLocationID = pEntry->dwPermanentLocationID;
  6399. dwCountryCode = pEntry->dwCountryCode;
  6400. dwPreferredCardID = pEntry->dwPreferredCardID;
  6401. dwCountryID = pEntry->dwCountryID;
  6402. dwOptions = pEntry->dwOptions;
  6403. // create our new LocationInfo Object
  6404. CComObject<CLocationInfo> * pLocationInfo;
  6405. CComObject<CLocationInfo>::CreateInstance( &pLocationInfo );
  6406. if (SUCCEEDED(hr) )
  6407. {
  6408. // initialize the new LocationInfo Object
  6409. hr = pLocationInfo->Initialize(
  6410. pszLocationName,
  6411. pszCityCode,
  6412. pszLocalAccessCode,
  6413. pszLongDistanceAccessCode,
  6414. pszTollPrefixList,
  6415. pszCancelCallWaitingCode ,
  6416. dwPermanentLocationID,
  6417. dwCountryCode,
  6418. dwPreferredCardID,
  6419. dwCountryID,
  6420. dwOptions
  6421. );
  6422. if (SUCCEEDED(hr) )
  6423. {
  6424. // Add it to the enumerator
  6425. hr = pEnum->Add(pLocationInfo);
  6426. if (SUCCEEDED(hr))
  6427. {
  6428. LOG((TL_INFO, "EnumerateLocations - Added LocationInfo object to enum"));
  6429. }
  6430. else
  6431. {
  6432. LOG((TL_INFO, "EnumerateLocations - Add LocationInfo object failed"));
  6433. delete pLocationInfo;
  6434. }
  6435. }
  6436. else
  6437. {
  6438. LOG((TL_ERROR, "EnumerateLocations - Init LocationInfo object failed"));
  6439. delete pLocationInfo;
  6440. }
  6441. }
  6442. else // CComObject::CreateInstance failed
  6443. {
  6444. LOG((TL_ERROR, "EnumerateLocations - Create LocationInfo object failed"));
  6445. }
  6446. // Try next location in list
  6447. pEntry++;
  6448. } //for(dwCount.....)
  6449. //
  6450. // return the Enumerator
  6451. //
  6452. *ppEnumLocation = pEnum;
  6453. }
  6454. else // LineGetTranslateCaps failed
  6455. {
  6456. LOG((TL_ERROR, "EnumerateLocations - LineGetTranslateCaps failed" ));
  6457. pEnum->Release();
  6458. }
  6459. }
  6460. else // CComObject::CreateInstance failed
  6461. {
  6462. LOG((TL_ERROR, "EnumerateLocations - could not create enum" ));
  6463. }
  6464. // finished with TAPI memory block so release
  6465. if ( pTranslateCaps != NULL )
  6466. ClientFree( pTranslateCaps );
  6467. }
  6468. LOG((TL_TRACE, hr, "EnumerateLocations - exit" ));
  6469. return hr;
  6470. }
  6471. STDMETHODIMP
  6472. CAddress::get_Locations(
  6473. VARIANT * pVariant
  6474. )
  6475. {
  6476. IEnumLocation * pEnumLocation;
  6477. HRESULT hr;
  6478. CComObject< CTapiCollection< ITLocationInfo > > * p;
  6479. LocationArray TempLocationArray;
  6480. ITLocationInfo * pLocation;
  6481. if ( TAPIIsBadWritePtr( pVariant, sizeof( VARIANT ) ) )
  6482. {
  6483. LOG((TL_ERROR, "get_locations - bad pointer"));
  6484. return E_POINTER;
  6485. }
  6486. //
  6487. // create collection object
  6488. //
  6489. CComObject< CTapiCollection< ITLocationInfo > >::CreateInstance( &p );
  6490. if (NULL == p)
  6491. {
  6492. LOG((TL_ERROR, "get_Locations - could not create collection" ));
  6493. return E_OUTOFMEMORY;
  6494. }
  6495. hr = EnumerateLocations ( &pEnumLocation );
  6496. if ( !SUCCEEDED(hr) )
  6497. {
  6498. delete p;
  6499. LOG((TL_ERROR, "get_locations - enumerate locations failed"));
  6500. return hr;
  6501. }
  6502. while (TRUE)
  6503. {
  6504. hr = pEnumLocation->Next(1, &pLocation, NULL);
  6505. if ( S_OK != hr )
  6506. {
  6507. break;
  6508. }
  6509. TempLocationArray.Add( pLocation );
  6510. pLocation->Release();
  6511. }
  6512. pEnumLocation->Release();
  6513. p->Initialize( TempLocationArray );
  6514. TempLocationArray.Shutdown();
  6515. IDispatch * pDisp;
  6516. //
  6517. // get the IDispatch interface
  6518. //
  6519. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  6520. if (S_OK != hr)
  6521. {
  6522. LOG((TL_ERROR, "get_Locations - could not get IDispatch interface" ));
  6523. delete p;
  6524. return hr;
  6525. }
  6526. //
  6527. // put it in the variant
  6528. //
  6529. VariantInit(pVariant);
  6530. pVariant->vt = VT_DISPATCH;
  6531. pVariant->pdispVal = pDisp;
  6532. LOG((TL_TRACE, "get_Locations exit - return success"));
  6533. return S_OK;
  6534. }
  6535. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6536. // Class : CAddress
  6537. // Interface : ITAddressTranslation
  6538. // Method : EnumerateCallingCards
  6539. //
  6540. //
  6541. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6542. STDMETHODIMP CAddress::EnumerateCallingCards (IEnumCallingCard ** ppCallingCards )
  6543. {
  6544. HRESULT hr = S_OK;
  6545. LPLINETRANSLATECAPS pTranslateCaps = NULL;
  6546. DWORD dwNumCards;
  6547. DWORD dwCount;
  6548. LPLINECARDENTRY pEntry = NULL;
  6549. PWSTR pszCardName;
  6550. PWSTR pszSameAreaDialingRule;
  6551. PWSTR pszLongDistanceDialingRule;
  6552. PWSTR pszInternationalDialingRule;
  6553. DWORD dwPermanentCardID;
  6554. DWORD dwNumberOfDigits;
  6555. DWORD dwOptions;
  6556. LOG((TL_TRACE, "EnumerateCallingCards - enter" ));
  6557. if ( TAPIIsBadWritePtr( ppCallingCards, sizeof(IEnumCallingCard *) ) )
  6558. {
  6559. LOG((TL_ERROR, "EnumerateCallingCards - Bad Pointer" ));
  6560. hr = E_POINTER;
  6561. }
  6562. else // Ok Pointer
  6563. {
  6564. //
  6565. // create the enumerator
  6566. //
  6567. CComObject< CTapiEnum<IEnumCallingCard, ITCallingCard, &IID_IEnumCallingCard> > * pEnum;
  6568. hr = CComObject< CTapiEnum<IEnumCallingCard, ITCallingCard, &IID_IEnumCallingCard> > ::CreateInstance( &pEnum );
  6569. if ( SUCCEEDED(hr) )
  6570. {
  6571. //
  6572. // initialize it with our Locations list
  6573. //
  6574. pEnum->Initialize();
  6575. hr = LineGetTranslateCaps(m_hLineApp, TAPI_CURRENT_VERSION, &pTranslateCaps);
  6576. if( SUCCEEDED(hr) )
  6577. {
  6578. dwNumCards = pTranslateCaps->dwNumCards ;
  6579. // Find positionn of 1st LINECARDENTRY structure in the LINETRANSLATECAPS structure
  6580. pEntry = (LPLINECARDENTRY) ((BYTE*)(pTranslateCaps) + pTranslateCaps->dwCardListOffset );
  6581. for (dwCount = 0; dwCount < dwNumCards; dwCount++)
  6582. {
  6583. // Pull Location Info out of LINECARDENTRY structure
  6584. pszCardName = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwCardNameOffset);
  6585. pszSameAreaDialingRule = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwSameAreaRuleOffset);
  6586. pszLongDistanceDialingRule = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwLongDistanceRuleOffset);
  6587. pszInternationalDialingRule = (PWSTR) ((BYTE*)(pTranslateCaps) + pEntry->dwInternationalRuleOffset);
  6588. dwPermanentCardID = pEntry->dwPermanentCardID;
  6589. dwNumberOfDigits = pEntry->dwCardNumberDigits;
  6590. dwOptions = pEntry->dwOptions;
  6591. // create our new CallingCard Object
  6592. CComObject<CCallingCard> * pCallingCard;
  6593. CComObject<CCallingCard>::CreateInstance( &pCallingCard );
  6594. if (SUCCEEDED(hr) )
  6595. {
  6596. // initialize the new CallingCard Object
  6597. hr = pCallingCard->Initialize(
  6598. pszCardName,
  6599. pszSameAreaDialingRule,
  6600. pszLongDistanceDialingRule,
  6601. pszInternationalDialingRule,
  6602. dwPermanentCardID,
  6603. dwNumberOfDigits,
  6604. dwOptions
  6605. );
  6606. if (SUCCEEDED(hr) )
  6607. {
  6608. // Add it to the enumerator
  6609. hr = pEnum->Add(pCallingCard);
  6610. if (SUCCEEDED(hr))
  6611. {
  6612. LOG((TL_INFO, "EnumerateCallingCards - Added CallingCard object to enum"));
  6613. }
  6614. else
  6615. {
  6616. LOG((TL_INFO, "EnumertateCallingCards - Add CallingCard object failed"));
  6617. delete pCallingCard;
  6618. }
  6619. }
  6620. else
  6621. {
  6622. LOG((TL_ERROR, "EnumerateCallingCards - Init CallingCard object failed"));
  6623. delete pCallingCard;
  6624. }
  6625. }
  6626. else // CComObject::CreateInstance failed
  6627. {
  6628. LOG((TL_ERROR, "EnumerateCallingCards - Create CallingCard object failed"));
  6629. }
  6630. // Try next card in list
  6631. pEntry++;
  6632. } //for(dwCount.....)
  6633. //
  6634. // return the Enumerator
  6635. //
  6636. *ppCallingCards = pEnum;
  6637. }
  6638. else // LineGetTranslateCaps failed
  6639. {
  6640. LOG((TL_ERROR, "EnumerateCallingCards - LineGetTranslateCaps failed" ));
  6641. pEnum->Release();
  6642. }
  6643. }
  6644. else // CComObject::CreateInstance failed
  6645. {
  6646. LOG((TL_ERROR, "EnumerateCallingCards - could not create enum" ));
  6647. }
  6648. // finished with TAPI memory block so release
  6649. if ( pTranslateCaps != NULL )
  6650. ClientFree( pTranslateCaps );
  6651. }
  6652. LOG((TL_TRACE, hr, "EnumerateCallingCards - exit" ));
  6653. return hr;
  6654. }
  6655. STDMETHODIMP
  6656. CAddress::get_CallingCards(
  6657. VARIANT * pVariant
  6658. )
  6659. {
  6660. IEnumCallingCard * pEnumCallingCards;
  6661. HRESULT hr;
  6662. CComObject< CTapiCollection< ITCallingCard > > * p;
  6663. CallingCardArray TempCallingCardArray;
  6664. ITCallingCard * pCallingCard;
  6665. if ( TAPIIsBadWritePtr( pVariant, sizeof( VARIANT ) ) )
  6666. {
  6667. LOG((TL_ERROR, "get_CallingCard - bad pointer"));
  6668. return E_POINTER;
  6669. }
  6670. //
  6671. // create collection object
  6672. //
  6673. CComObject< CTapiCollection< ITCallingCard > >::CreateInstance( &p );
  6674. if (NULL == p)
  6675. {
  6676. LOG((TL_ERROR, "get_CallingCards - could not create collection" ));
  6677. return E_OUTOFMEMORY;
  6678. }
  6679. hr = EnumerateCallingCards ( &pEnumCallingCards );
  6680. if ( !SUCCEEDED(hr) )
  6681. {
  6682. delete p;
  6683. LOG((TL_ERROR, "get_CallingCards - enumerate callingcards failed"));
  6684. return hr;
  6685. }
  6686. while (TRUE)
  6687. {
  6688. hr = pEnumCallingCards->Next(1, &pCallingCard, NULL);
  6689. if ( S_OK != hr )
  6690. {
  6691. break;
  6692. }
  6693. TempCallingCardArray.Add( pCallingCard );
  6694. pCallingCard->Release();
  6695. }
  6696. pEnumCallingCards->Release();
  6697. p->Initialize( TempCallingCardArray );
  6698. TempCallingCardArray.Shutdown();
  6699. IDispatch * pDisp;
  6700. //
  6701. // get the IDispatch interface
  6702. //
  6703. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  6704. if (S_OK != hr)
  6705. {
  6706. LOG((TL_ERROR, "get_CallingCards - could not get IDispatch interface" ));
  6707. delete p;
  6708. return hr;
  6709. }
  6710. //
  6711. // put it in the variant
  6712. //
  6713. VariantInit(pVariant);
  6714. pVariant->vt = VT_DISPATCH;
  6715. pVariant->pdispVal = pDisp;
  6716. LOG((TL_TRACE, "get_CallingCards exit - return success"));
  6717. return S_OK;
  6718. }
  6719. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6720. // Class : CAddress
  6721. // Method : GetPhoneArrayFromTapiAndPrune
  6722. //
  6723. //
  6724. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6725. HRESULT
  6726. CAddress::GetPhoneArrayFromTapiAndPrune(
  6727. PhoneArray *pPhoneArray,
  6728. BOOL bPreferredOnly
  6729. )
  6730. {
  6731. HRESULT hr;
  6732. CTAPI * pCTapi;
  6733. ITPhone * pPhone;
  6734. CPhone * pCPhone;
  6735. LOG((TL_TRACE, "GetPhoneArrayFromTapiAndPrune enter"));
  6736. if ( IsBadReadPtr( pPhoneArray, sizeof( PhoneArray ) ) )
  6737. {
  6738. LOG((TL_ERROR, "GetPhoneArrayFromTapiAndPrune - bad pointer"));
  6739. return E_POINTER;
  6740. }
  6741. pCTapi = GetTapi();
  6742. if( NULL == pCTapi )
  6743. {
  6744. LOG((TL_ERROR, "dynamic cast operation failed"));
  6745. hr = E_POINTER;
  6746. }
  6747. else
  6748. {
  6749. hr = pCTapi->GetPhoneArray( pPhoneArray );
  6750. if ( SUCCEEDED(hr) )
  6751. {
  6752. //
  6753. // Go through the phones
  6754. //
  6755. for(int iCount = 0; iCount < pPhoneArray->GetSize(); iCount++)
  6756. {
  6757. pPhone = (*pPhoneArray)[iCount];
  6758. pCPhone = dynamic_cast<CPhone *>(pPhone);
  6759. if ( NULL == pCPhone )
  6760. {
  6761. //
  6762. // We have a bad pointer in our phone array.
  6763. // Lets skip it and move on.
  6764. //
  6765. _ASSERTE(FALSE);
  6766. continue;
  6767. }
  6768. //
  6769. // Is the phone on this address?
  6770. //
  6771. if ( bPreferredOnly ? pCPhone->IsPhoneOnPreferredAddress(this) : pCPhone->IsPhoneOnAddress(this) )
  6772. {
  6773. LOG((TL_INFO, "GetPhoneArrayFromTapiAndPrune - found matching phone - %p", pPhone));
  6774. }
  6775. else
  6776. {
  6777. // No, remove it from the array
  6778. pPhoneArray->RemoveAt(iCount);
  6779. iCount--;
  6780. }
  6781. }
  6782. }
  6783. }
  6784. LOG((TL_TRACE, "GetPhoneArrayFromTapiAndPrune - exit - return %lx", hr ));
  6785. return hr;
  6786. }
  6787. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6788. // Class : CAddress
  6789. // Interface : ITAddress2
  6790. // Method : get_Phones
  6791. //
  6792. //
  6793. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6794. HRESULT
  6795. CAddress::get_Phones(
  6796. VARIANT * pPhones
  6797. )
  6798. {
  6799. HRESULT hr;
  6800. IDispatch * pDisp;
  6801. PhoneArray PhoneArray;
  6802. LOG((TL_TRACE, "get_Phones enter"));
  6803. if ( TAPIIsBadWritePtr( pPhones, sizeof( VARIANT ) ) )
  6804. {
  6805. LOG((TL_ERROR, "get_Phones - bad pointer"));
  6806. return E_POINTER;
  6807. }
  6808. hr = GetPhoneArrayFromTapiAndPrune( &PhoneArray, FALSE );
  6809. if ( SUCCEEDED(hr) )
  6810. {
  6811. CComObject< CTapiCollection< ITPhone > > * p;
  6812. CComObject< CTapiCollection< ITPhone > >::CreateInstance( &p );
  6813. if (NULL == p)
  6814. {
  6815. LOG((TL_ERROR, "get_Phones - could not create collection" ));
  6816. PhoneArray.Shutdown();
  6817. return E_OUTOFMEMORY;
  6818. }
  6819. // get the IDispatch interface
  6820. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  6821. if (S_OK != hr)
  6822. {
  6823. LOG((TL_ERROR, "get_Phones - could not get IDispatch interface" ));
  6824. delete p;
  6825. return hr;
  6826. }
  6827. Lock();
  6828. // initialize
  6829. hr = p->Initialize( PhoneArray );
  6830. Unlock();
  6831. PhoneArray.Shutdown();
  6832. if (S_OK != hr)
  6833. {
  6834. LOG((TL_ERROR, "get_Phones - could not initialize collection" ));
  6835. pDisp->Release();
  6836. return hr;
  6837. }
  6838. // put it in the variant
  6839. VariantInit(pPhones);
  6840. pPhones->vt = VT_DISPATCH;
  6841. pPhones->pdispVal = pDisp;
  6842. }
  6843. LOG((TL_TRACE, "get_Phones - exit - return %lx", hr ));
  6844. return hr;
  6845. }
  6846. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6847. // Class : CAddress
  6848. // Interface : ITAddress2
  6849. // Method : EnumeratePhones
  6850. //
  6851. //
  6852. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6853. HRESULT
  6854. CAddress::EnumeratePhones(
  6855. IEnumPhone ** ppEnumPhone
  6856. )
  6857. {
  6858. HRESULT hr;
  6859. PhoneArray PhoneArray;
  6860. LOG((TL_TRACE, "EnumeratePhones - enter"));
  6861. LOG((TL_TRACE, " ppEnumPhone----->%p", ppEnumPhone ));
  6862. if ( TAPIIsBadWritePtr( ppEnumPhone, sizeof( IEnumPhone * ) ) )
  6863. {
  6864. LOG((TL_ERROR, "EnumeratePhones - bad pointer"));
  6865. return E_POINTER;
  6866. }
  6867. hr = GetPhoneArrayFromTapiAndPrune( &PhoneArray, FALSE );
  6868. if ( SUCCEEDED(hr) )
  6869. {
  6870. //
  6871. // create the enumerator
  6872. //
  6873. CComObject< CTapiEnum< IEnumPhone, ITPhone, &IID_IEnumPhone > > * p;
  6874. try
  6875. {
  6876. hr = CComObject< CTapiEnum< IEnumPhone, ITPhone, &IID_IEnumPhone > >
  6877. ::CreateInstance( &p );
  6878. }
  6879. catch(...)
  6880. {
  6881. LOG((TL_ERROR,
  6882. "EnumeratePhones - failed to create phone enumeration. exception thrown." ));
  6883. hr = E_OUTOFMEMORY;
  6884. }
  6885. if (S_OK != hr)
  6886. {
  6887. LOG((TL_ERROR, "EnumeratePhones - could not create enum" ));
  6888. PhoneArray.Shutdown();
  6889. return hr;
  6890. }
  6891. Lock();
  6892. // initialize it with our phone list
  6893. p->Initialize( PhoneArray );
  6894. Unlock();
  6895. PhoneArray.Shutdown();
  6896. //
  6897. // return it
  6898. //
  6899. *ppEnumPhone = p;
  6900. }
  6901. LOG((TL_TRACE, "EnumeratePhones - exit - return %lx", hr ));
  6902. return hr;
  6903. }
  6904. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6905. // Class : CAddress
  6906. // Interface : ITAddress2
  6907. // Method : get_PreferredPhones
  6908. //
  6909. //
  6910. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6911. HRESULT
  6912. CAddress::get_PreferredPhones(
  6913. VARIANT * pPhones
  6914. )
  6915. {
  6916. HRESULT hr;
  6917. IDispatch * pDisp;
  6918. PhoneArray PhoneArray;
  6919. LOG((TL_TRACE, "get_PreferredPhones enter"));
  6920. if ( TAPIIsBadWritePtr( pPhones, sizeof( VARIANT ) ) )
  6921. {
  6922. LOG((TL_ERROR, "get_PreferredPhones - bad pointer"));
  6923. return E_POINTER;
  6924. }
  6925. hr = GetPhoneArrayFromTapiAndPrune( &PhoneArray, TRUE );
  6926. if ( SUCCEEDED(hr) )
  6927. {
  6928. CComObject< CTapiCollection< ITPhone > > * p;
  6929. CComObject< CTapiCollection< ITPhone > >::CreateInstance( &p );
  6930. if (NULL == p)
  6931. {
  6932. LOG((TL_ERROR, "get_PreferredPhones - could not create collection" ));
  6933. PhoneArray.Shutdown();
  6934. return E_OUTOFMEMORY;
  6935. }
  6936. // get the IDispatch interface
  6937. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  6938. if (S_OK != hr)
  6939. {
  6940. LOG((TL_ERROR, "get_PreferredPhones - could not get IDispatch interface" ));
  6941. delete p;
  6942. return hr;
  6943. }
  6944. Lock();
  6945. // initialize
  6946. hr = p->Initialize( PhoneArray );
  6947. Unlock();
  6948. PhoneArray.Shutdown();
  6949. if (S_OK != hr)
  6950. {
  6951. LOG((TL_ERROR, "get_PreferredPhones - could not initialize collection" ));
  6952. pDisp->Release();
  6953. return hr;
  6954. }
  6955. // put it in the variant
  6956. VariantInit(pPhones);
  6957. pPhones->vt = VT_DISPATCH;
  6958. pPhones->pdispVal = pDisp;
  6959. }
  6960. LOG((TL_TRACE, "get_PreferredPhones - exit - return %lx", hr ));
  6961. return hr;
  6962. }
  6963. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6964. // Class : CAddress
  6965. // Interface : ITAddress2
  6966. // Method : EnumeratePreferredPhones
  6967. //
  6968. //
  6969. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6970. HRESULT
  6971. CAddress::EnumeratePreferredPhones(
  6972. IEnumPhone ** ppEnumPhone
  6973. )
  6974. {
  6975. HRESULT hr;
  6976. PhoneArray PhoneArray;
  6977. LOG((TL_TRACE, "EnumeratePreferredPhones - enter"));
  6978. LOG((TL_TRACE, " ppEnumPhone----->%p", ppEnumPhone ));
  6979. if ( TAPIIsBadWritePtr( ppEnumPhone, sizeof( IEnumPhone * ) ) )
  6980. {
  6981. LOG((TL_ERROR, "EnumeratePreferredPhones - bad pointer"));
  6982. return E_POINTER;
  6983. }
  6984. hr = GetPhoneArrayFromTapiAndPrune( &PhoneArray, TRUE );
  6985. if ( SUCCEEDED(hr) )
  6986. {
  6987. //
  6988. // create the enumerator
  6989. //
  6990. CComObject< CTapiEnum< IEnumPhone, ITPhone, &IID_IEnumPhone > > * p;
  6991. hr = CComObject< CTapiEnum< IEnumPhone, ITPhone, &IID_IEnumPhone > >
  6992. ::CreateInstance( &p );
  6993. if (S_OK != hr)
  6994. {
  6995. LOG((TL_ERROR, "EnumeratePreferredPhones - could not create enum" ));
  6996. PhoneArray.Shutdown();
  6997. return hr;
  6998. }
  6999. Lock();
  7000. // initialize it with our phone list
  7001. p->Initialize( PhoneArray );
  7002. Unlock();
  7003. PhoneArray.Shutdown();
  7004. //
  7005. // return it
  7006. //
  7007. *ppEnumPhone = p;
  7008. }
  7009. LOG((TL_TRACE, "EnumeratePreferredPhones - exit - return %lx", hr ));
  7010. return hr;
  7011. }
  7012. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7013. // Class : CAddress
  7014. // Interface : ITAddress2
  7015. // Method : GetPhoneFromTerminal
  7016. //
  7017. //
  7018. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7019. HRESULT CAddress::GetPhoneFromTerminal(
  7020. ITTerminal * pTerminal,
  7021. ITPhone ** ppPhone
  7022. )
  7023. {
  7024. HRESULT hr = E_FAIL;
  7025. PhoneArray PhoneArray;
  7026. ITStaticAudioTerminal * pStaticAudioTerminal;
  7027. LONG lMediaType;
  7028. TERMINAL_DIRECTION nDir;
  7029. LOG((TL_TRACE, "GetPhoneFromTerminal - enter"));
  7030. if ( TAPIIsBadWritePtr( ppPhone, sizeof( ITPhone * ) ) ||
  7031. IsBadReadPtr( pTerminal, sizeof( ITTerminal ) ) )
  7032. {
  7033. LOG((TL_ERROR, "GetPhoneFromTerminal - bad pointer"));
  7034. return E_POINTER;
  7035. }
  7036. *ppPhone = NULL;
  7037. if ( SUCCEEDED(pTerminal->get_MediaType(&lMediaType)) &&
  7038. SUCCEEDED(pTerminal->get_Direction(&nDir)) &&
  7039. (lMediaType == TAPIMEDIATYPE_AUDIO) )
  7040. {
  7041. hr = pTerminal->QueryInterface(IID_ITStaticAudioTerminal, (void **) &pStaticAudioTerminal);
  7042. if ( SUCCEEDED(hr) )
  7043. {
  7044. LONG lWaveId;
  7045. hr = pStaticAudioTerminal->get_WaveId(&lWaveId);
  7046. if ( SUCCEEDED(hr) )
  7047. {
  7048. LOG((TL_INFO, "GetPhoneFromTerminal - got terminal wave id %d", lWaveId));
  7049. hr = GetPhoneArrayFromTapiAndPrune( &PhoneArray, FALSE );
  7050. if ( SUCCEEDED(hr) )
  7051. {
  7052. ITPhone * pPhone;
  7053. CPhone * pCPhone;
  7054. int iPhoneCount;
  7055. hr = TAPI_E_NODEVICE;
  7056. for(iPhoneCount = 0; iPhoneCount < PhoneArray.GetSize(); iPhoneCount++)
  7057. {
  7058. pPhone = PhoneArray[iPhoneCount];
  7059. pCPhone = dynamic_cast<CPhone *>(pPhone);
  7060. if ( NULL == pCPhone )
  7061. {
  7062. //
  7063. // We have a bad pointer in our phone array.
  7064. // Lets skip it and move on.
  7065. //
  7066. _ASSERTE(FALSE);
  7067. continue;
  7068. }
  7069. if (pCPhone->IsPhoneUsingWaveID( lWaveId, nDir ))
  7070. {
  7071. *ppPhone = pPhone;
  7072. pPhone->AddRef();
  7073. hr = S_OK;
  7074. break;
  7075. }
  7076. }
  7077. PhoneArray.Shutdown();
  7078. }
  7079. }
  7080. pStaticAudioTerminal->Release();
  7081. }
  7082. }
  7083. LOG((TL_TRACE, "GetPhoneFromTerminal - exit - return %lx", hr ));
  7084. return hr;
  7085. }
  7086. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7087. // Class : CAddress
  7088. // Interface : ITAddress2
  7089. // Method : put_EventFilter
  7090. //
  7091. //
  7092. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7093. HRESULT
  7094. CAddress::put_EventFilter(
  7095. TAPI_EVENT TapiEvent,
  7096. long lSubEvent,
  7097. VARIANT_BOOL bEnable
  7098. )
  7099. {
  7100. LOG((TL_TRACE, "put_EventFilter - enter"));
  7101. //
  7102. // Validates the pair TapiEvent - lSubEvent
  7103. // Accept also all subevents
  7104. //
  7105. if( !m_EventMasks.IsSubEventValid( TapiEvent, lSubEvent, TRUE, FALSE) )
  7106. {
  7107. LOG((TL_ERROR, "put_EventFilter - "
  7108. "This event can't be set: %x, return E_INVALIDARG", TapiEvent ));
  7109. return E_INVALIDARG;
  7110. }
  7111. // Enter critical section
  7112. Lock();
  7113. // Set the subevent flag
  7114. HRESULT hr = E_FAIL;
  7115. hr = SetSubEventFlag(
  7116. TapiEvent,
  7117. (DWORD)lSubEvent,
  7118. (bEnable == VARIANT_TRUE)
  7119. );
  7120. // Leave critical section
  7121. Unlock();
  7122. return hr;
  7123. }
  7124. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7125. // Class : CAddress
  7126. // Interface : ITAddress2
  7127. // Method : get_EventFilter
  7128. //
  7129. //
  7130. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7131. HRESULT
  7132. CAddress::get_EventFilter(
  7133. TAPI_EVENT TapiEvent,
  7134. long lSubEvent,
  7135. VARIANT_BOOL* pEnable
  7136. )
  7137. {
  7138. LOG((TL_TRACE, "get_EventFilter - enter"));
  7139. //
  7140. // Validates output argument
  7141. //
  7142. if( IsBadReadPtr(pEnable, sizeof(VARIANT_BOOL)) )
  7143. {
  7144. LOG((TL_ERROR, "get_EventFilter - "
  7145. "invalid VARIANT_BOOL pointer, return E_POINTER" ));
  7146. return E_POINTER;
  7147. }
  7148. //
  7149. // Validates the pair TapiEvent - lSubEvent
  7150. // Don't accept all subevents
  7151. //
  7152. if( !m_EventMasks.IsSubEventValid( TapiEvent, lSubEvent, FALSE, FALSE) )
  7153. {
  7154. LOG((TL_ERROR, "get_EventFilter - "
  7155. "This event can't be set: %x, return E_INVALIDARG", TapiEvent ));
  7156. return E_INVALIDARG;
  7157. }
  7158. // Enter critical section
  7159. Lock();
  7160. //
  7161. // Get the subevent mask for that (event, subevent) pair
  7162. //
  7163. BOOL bEnable = FALSE;
  7164. HRESULT hr = GetSubEventFlag(
  7165. TapiEvent,
  7166. (DWORD)lSubEvent,
  7167. &bEnable);
  7168. if( FAILED(hr) )
  7169. {
  7170. LOG((TL_ERROR, "get_EventFilter - "
  7171. "GetSubEventFlag failed, return 0x%08x", hr ));
  7172. // Leave critical section
  7173. Unlock();
  7174. return hr;
  7175. }
  7176. //
  7177. // Set the output argument
  7178. //
  7179. *pEnable = bEnable ? VARIANT_TRUE : VARIANT_FALSE;
  7180. // Leave critical section
  7181. Unlock();
  7182. LOG((TL_TRACE, "get_EventFilter - exit S_OK"));
  7183. return S_OK;
  7184. }
  7185. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7186. // Class : CAddress
  7187. // Interface : ITAddress2
  7188. // Method : DeviceSpecific
  7189. //
  7190. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7191. HRESULT CAddress::DeviceSpecific(
  7192. IN ITCallInfo *pCall,
  7193. IN BYTE *pbDataArray,
  7194. IN DWORD dwSize
  7195. )
  7196. {
  7197. LOG((TL_TRACE, "DeviceSpecific - enter"));
  7198. //
  7199. // check if arguments are any good
  7200. //
  7201. if ( NULL == pbDataArray )
  7202. {
  7203. LOG((TL_ERROR, "DeviceSpecific - pbDataArray is NULL. E_INVALIDARG"));
  7204. return E_INVALIDARG;
  7205. }
  7206. if ( 0 == dwSize )
  7207. {
  7208. LOG((TL_ERROR, "DeviceSpecific - dwSize is 0. E_INVALIDARG"));
  7209. return E_INVALIDARG;
  7210. }
  7211. //
  7212. // check if the buffer is valid
  7213. //
  7214. if ( IsBadReadPtr(pbDataArray, dwSize) )
  7215. {
  7216. LOG((TL_ERROR,
  7217. "DeviceSpecific - bad array passed in [%p] of size %ld",
  7218. pbDataArray, dwSize));
  7219. return E_POINTER;
  7220. }
  7221. //
  7222. // see if the call is obviously bad, and try to get call object pointer if
  7223. // it is good
  7224. //
  7225. CCall *pCallObject = NULL;
  7226. if ( (NULL != pCall) )
  7227. {
  7228. //
  7229. // does it point to readable memory at all?
  7230. //
  7231. if ( IsBadReadPtr(pCall, sizeof(ITCallInfo)) )
  7232. {
  7233. LOG((TL_ERROR, "DeviceSpecific - unreadable call pointer [%p]", pCall));
  7234. return E_POINTER;
  7235. }
  7236. //
  7237. // see if call is pointing to a real call object
  7238. //
  7239. try
  7240. {
  7241. pCallObject = dynamic_cast<CCall*>(pCall);
  7242. }
  7243. catch (...)
  7244. {
  7245. //
  7246. // call pointer is really really bad
  7247. //
  7248. LOG((TL_ERROR,
  7249. "DeviceSpecific - exception casting call pointer to a call object, bad call [%p]",
  7250. pCall));
  7251. }
  7252. //
  7253. // if we could not get the call object pointer, this is not a good call
  7254. //
  7255. if (NULL == pCallObject)
  7256. {
  7257. LOG((TL_ERROR,
  7258. "DeviceSpecific - could not get call object from call pointer -- bad call pointer argument [%p]",
  7259. pCall));
  7260. return E_POINTER;
  7261. }
  7262. } // received call pointer that is NULL?
  7263. //
  7264. // by this point we know pCall is either NULL or we have a call pointer
  7265. // that seems (but not guaranteed) to be good
  7266. //
  7267. //
  7268. // prepare all the data for the call to lineDevSpecific
  7269. //
  7270. //
  7271. // get hcall from the call
  7272. //
  7273. HCALL hCall = NULL;
  7274. if (NULL != pCallObject)
  7275. {
  7276. hCall = pCallObject->GetHCall();
  7277. //
  7278. // if we there is no call handle, return an error -- the app did not
  7279. // called Connect on the call
  7280. //
  7281. if (NULL == hCall)
  7282. {
  7283. LOG((TL_ERROR,
  7284. "DeviceSpecific - no call handle. hr = TAPI_E_INVALCALLSTATE",
  7285. pCall));
  7286. return TAPI_E_INVALCALLSTATE;
  7287. }
  7288. }
  7289. //
  7290. // starting to access data members. lock.
  7291. //
  7292. Lock();
  7293. //
  7294. // get a line to use to communicate devspecific information
  7295. //
  7296. AddressLineStruct *pAddressLine = NULL;
  7297. HRESULT hr = FindOrOpenALine(m_dwMediaModesSupported, &pAddressLine);
  7298. if (FAILED(hr))
  7299. {
  7300. Unlock();
  7301. LOG((TL_TRACE, "DeviceSpecific - FindOrOpenALine failed. hr = %lx", hr));
  7302. return hr;
  7303. }
  7304. DWORD dwAddressID = m_dwAddressID;
  7305. Unlock();
  7306. //
  7307. // make the tapisrv call
  7308. //
  7309. hr = lineDevSpecific( pAddressLine->t3Line.hLine,
  7310. dwAddressID,
  7311. hCall,
  7312. pbDataArray,
  7313. dwSize
  7314. );
  7315. //
  7316. // no longer need the line. if registered for address notifications, the
  7317. // line will remain opened. otherwise, if no one has the line open, it will
  7318. // close -- we are not processing incoming events anyway.
  7319. //
  7320. MaybeCloseALine(&pAddressLine);
  7321. LOG((TL_TRACE, "DeviceSpecific - exit. hr = %lx", hr));
  7322. return hr;
  7323. }
  7324. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7325. // Class : CAddress
  7326. // Interface : ITAddress2
  7327. // Method : DeviceSpecificVariant
  7328. //
  7329. // this is the scriptable version of DeviceSpecific
  7330. //
  7331. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7332. HRESULT CAddress::DeviceSpecificVariant(
  7333. IN ITCallInfo *pCall,
  7334. IN VARIANT varDevSpecificByteArray
  7335. )
  7336. {
  7337. LOG((TL_TRACE, "DeviceSpecificVariant - enter"));
  7338. //
  7339. // extract buffer from the variant
  7340. //
  7341. DWORD dwByteArraySize = 0;
  7342. BYTE *pBuffer = NULL;
  7343. HRESULT hr = E_FAIL;
  7344. hr = MakeBufferFromVariant(varDevSpecificByteArray, &dwByteArraySize, &pBuffer);
  7345. if (FAILED(hr))
  7346. {
  7347. LOG((TL_TRACE, "DeviceSpecificVariant - MakeBufferFromVariant failed. hr = %lx", hr));
  7348. return hr;
  7349. }
  7350. //
  7351. // call the non-scriptable version and pass it the nonscriptable implementation
  7352. //
  7353. hr = DeviceSpecific(pCall, pBuffer, dwByteArraySize);
  7354. //
  7355. // success or failure, free the buffer allocated by MakeBufferFromVariant
  7356. //
  7357. ClientFree(pBuffer);
  7358. pBuffer = NULL;
  7359. //
  7360. // log rc and exit
  7361. //
  7362. LOG((TL_TRACE, "DeviceSpecificVariant - exit. hr = %lx", hr));
  7363. return hr;
  7364. }
  7365. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7366. // Class : CAddress
  7367. // Interface : ITAddress2
  7368. // Method : NegotiateExtVersion
  7369. //
  7370. //
  7371. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7372. HRESULT CAddress::NegotiateExtVersion (
  7373. IN long lLowVersion,
  7374. IN long lHighVersion,
  7375. OUT long *plExtVersion
  7376. )
  7377. {
  7378. LOG((TL_TRACE, "NegotiateExtVersion - enter"));
  7379. //
  7380. // make sure the out parameter is writable
  7381. //
  7382. if (IsBadWritePtr(plExtVersion, sizeof(long)) )
  7383. {
  7384. LOG((TL_ERROR, "NegotiateExtVersion - output arg [%p] not writeable", plExtVersion));
  7385. return E_POINTER;
  7386. }
  7387. Lock();
  7388. //
  7389. // make a call to tapisrv
  7390. //
  7391. DWORD dwNegotiatedVersion = 0;
  7392. LONG lResult = lineNegotiateExtVersion( m_hLineApp,
  7393. m_dwDeviceID,
  7394. m_dwAPIVersion,
  7395. lLowVersion,
  7396. lHighVersion,
  7397. &dwNegotiatedVersion );
  7398. Unlock();
  7399. HRESULT hr = mapTAPIErrorCode(lResult);
  7400. //
  7401. // return the value on success
  7402. //
  7403. if ( SUCCEEDED(hr) )
  7404. {
  7405. LOG((TL_TRACE, "NegotiateExtVersion - negotiated version %ld", dwNegotiatedVersion));
  7406. *plExtVersion = dwNegotiatedVersion;
  7407. }
  7408. LOG((TL_TRACE, "NegotiateExtVersion - exit. hr = %lx", hr));
  7409. return hr;
  7410. }
  7411. //
  7412. // ----------------------- CAddressTranslationInfo -----------------------------
  7413. //
  7414. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7415. // Class : CAddressTranslationInfo
  7416. // Method : Initialize
  7417. //
  7418. //
  7419. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7420. HRESULT
  7421. CAddressTranslationInfo::Initialize(
  7422. PWSTR pszDialableString,
  7423. PWSTR pszDisplayableString,
  7424. DWORD dwCurrentCountry,
  7425. DWORD dwDestCountry,
  7426. DWORD dwTranslateResults
  7427. )
  7428. {
  7429. HRESULT hr = S_OK;
  7430. LOG((TL_TRACE, "Initialize - enter" ));
  7431. Lock();
  7432. m_dwCurrentCountryCode = dwCurrentCountry;
  7433. m_dwDestinationCountryCode = dwDestCountry;
  7434. m_dwTranslationResults = dwTranslateResults;
  7435. m_szDialableString = NULL;
  7436. m_szDialableString = NULL;
  7437. // copy the Dialable String
  7438. if (pszDialableString!= NULL)
  7439. {
  7440. m_szDialableString = (PWSTR) ClientAlloc((lstrlenW(pszDialableString) + 1) * sizeof (WCHAR));
  7441. if (m_szDialableString != NULL)
  7442. {
  7443. lstrcpyW(m_szDialableString, pszDialableString);
  7444. // Now copy the Displayable String
  7445. if (pszDisplayableString!= NULL)
  7446. {
  7447. m_szDisplayableString = (PWSTR) ClientAlloc((lstrlenW(pszDisplayableString) + 1) * sizeof (WCHAR));
  7448. if (m_szDisplayableString != NULL)
  7449. {
  7450. lstrcpyW(m_szDisplayableString, pszDisplayableString);
  7451. }
  7452. else
  7453. {
  7454. LOG((TL_ERROR, "Initialize - Alloc m_szDisplayableString failed" ));
  7455. ClientFree( pszDialableString );
  7456. pszDialableString = NULL;
  7457. hr = E_OUTOFMEMORY;
  7458. }
  7459. }
  7460. }
  7461. else
  7462. {
  7463. LOG((TL_ERROR, "Initialize - Alloc m_szDialableString failed" ));
  7464. hr = E_OUTOFMEMORY;
  7465. }
  7466. }
  7467. Unlock();
  7468. LOG((TL_TRACE, hr, "Initialize - exit" ));
  7469. return hr;
  7470. }
  7471. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7472. // Class : CAddressTranslationInfo
  7473. // Method : FinalRelease
  7474. //
  7475. //
  7476. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7477. void CAddressTranslationInfo::FinalRelease()
  7478. {
  7479. LOG((TL_TRACE, "FinalRelease - enter" ));
  7480. if (m_szDialableString != NULL)
  7481. {
  7482. ClientFree( m_szDialableString);
  7483. }
  7484. if (m_szDisplayableString != NULL)
  7485. {
  7486. ClientFree( m_szDisplayableString);
  7487. }
  7488. LOG((TL_TRACE, "FinalRelease - exit" ));
  7489. }
  7490. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7491. // Class : CAddressTranslationInfo
  7492. // Interface : ITAddressTranslationInfo
  7493. // Method : get_CurrentCountryCode
  7494. //
  7495. //
  7496. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7497. STDMETHODIMP
  7498. CAddressTranslationInfo::get_CurrentCountryCode(long * CountryCode )
  7499. {
  7500. HRESULT hr = S_OK;
  7501. LOG((TL_TRACE, "get_CurrentCountryCode - enter" ));
  7502. Lock();
  7503. if ( TAPIIsBadWritePtr( CountryCode , sizeof(long) ) )
  7504. {
  7505. LOG((TL_ERROR, "get_CurrentCountryCode - Bad Pointer" ));
  7506. hr = E_POINTER;
  7507. }
  7508. else // Ok Pointer
  7509. {
  7510. *CountryCode = m_dwCurrentCountryCode;
  7511. }
  7512. Unlock();
  7513. LOG((TL_TRACE, hr, "get_CurrentCountryCode - exit" ));
  7514. return hr;
  7515. }
  7516. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7517. // Class : CAddressTranslationInfo
  7518. // Interface : ITAddressTranslationInfo
  7519. // Method : get_DestinationCountryCode
  7520. //
  7521. //
  7522. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7523. STDMETHODIMP
  7524. CAddressTranslationInfo::get_DestinationCountryCode(long * CountryCode )
  7525. {
  7526. HRESULT hr = S_OK;
  7527. LOG((TL_TRACE, "get_DestinationCountryCode - enter" ));
  7528. Lock();
  7529. if ( TAPIIsBadWritePtr( CountryCode , sizeof(long) ) )
  7530. {
  7531. LOG((TL_ERROR, "get_DestinationCountryCode - Bad Pointer" ));
  7532. hr = E_POINTER;
  7533. }
  7534. else // Ok Pointer
  7535. {
  7536. *CountryCode = m_dwDestinationCountryCode;
  7537. }
  7538. Unlock();
  7539. LOG((TL_TRACE, hr, "get_DestinationCountryCode - exit" ));
  7540. return hr;
  7541. }
  7542. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7543. // Class : CAddressTranslationInfo
  7544. // Interface : ITAddressTranslationInfo
  7545. // Method : get_TranslationResult
  7546. //
  7547. //
  7548. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7549. STDMETHODIMP
  7550. CAddressTranslationInfo::get_TranslationResults(long * Results )
  7551. {
  7552. HRESULT hr = S_OK;
  7553. LOG((TL_TRACE, "get_TranslationResults - enter" ));
  7554. Lock();
  7555. if ( TAPIIsBadWritePtr( Results , sizeof(long) ) )
  7556. {
  7557. LOG((TL_ERROR, "get_TranslationResults - Bad Pointer" ));
  7558. hr = E_POINTER;
  7559. }
  7560. else // Ok Pointer
  7561. {
  7562. *Results = m_dwTranslationResults;
  7563. }
  7564. Unlock();
  7565. LOG((TL_TRACE, hr, "get_TranslationResults - exit" ));
  7566. return hr;
  7567. }
  7568. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7569. // Class : CAddressTranslationInfo
  7570. // Interface : ITAddressTranslationInfo
  7571. // Method : get_DialableString
  7572. //
  7573. //
  7574. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7575. STDMETHODIMP
  7576. CAddressTranslationInfo::get_DialableString(BSTR * ppDialableString)
  7577. {
  7578. HRESULT hr = S_OK;
  7579. LOG((TL_TRACE, "get_DialableString - enter" ));
  7580. Lock();
  7581. if ( TAPIIsBadWritePtr( ppDialableString, sizeof(BSTR) ) )
  7582. {
  7583. LOG((TL_ERROR, "get_DialableString - Bad Pointer" ));
  7584. hr = E_POINTER;
  7585. }
  7586. else // Ok Pointer
  7587. {
  7588. *ppDialableString = SysAllocString( m_szDialableString );
  7589. if ( ( NULL == *ppDialableString ) && ( NULL != m_szDialableString ) )
  7590. {
  7591. LOG((TL_TRACE, "SysAllocString Failed" ));
  7592. hr = E_OUTOFMEMORY;
  7593. }
  7594. }
  7595. Unlock();
  7596. LOG((TL_TRACE, hr, "get_DialableString - exit" ));
  7597. return hr;
  7598. }
  7599. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7600. // Class : CAddressTranslationInfo
  7601. // Interface : ITAddressTranslationInfo
  7602. // Method : get_DisplayableString
  7603. //
  7604. //
  7605. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7606. STDMETHODIMP
  7607. CAddressTranslationInfo::get_DisplayableString(BSTR * ppDisplayableString)
  7608. {
  7609. HRESULT hr = S_OK;
  7610. LOG((TL_TRACE, "get_DisplayableString - enter" ));
  7611. Lock();
  7612. if ( TAPIIsBadWritePtr( ppDisplayableString, sizeof(BSTR) ) )
  7613. {
  7614. LOG((TL_ERROR, "get_DisplayableString - Bad Pointer" ));
  7615. hr = E_POINTER;
  7616. }
  7617. else // Ok Pointer
  7618. {
  7619. *ppDisplayableString = SysAllocString( m_szDisplayableString );
  7620. if ( ( NULL == *ppDisplayableString ) && ( NULL != m_szDisplayableString ) )
  7621. {
  7622. LOG((TL_TRACE, "SysAllocString Failed" ));
  7623. hr = E_OUTOFMEMORY;
  7624. }
  7625. }
  7626. Unlock();
  7627. LOG((TL_TRACE, hr, "get_DisplayableString - exit" ));
  7628. return hr;
  7629. }
  7630. //
  7631. // ----------------------- CCallingCard -----------------------------
  7632. //
  7633. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7634. // Class : CCallingCard
  7635. // Method : Initialize
  7636. //
  7637. //
  7638. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7639. HRESULT
  7640. CCallingCard::Initialize(
  7641. PWSTR pszCardName,
  7642. PWSTR pszSameAreaDialingRule,
  7643. PWSTR pszLongDistanceDialingRule,
  7644. PWSTR pszInternationalDialingRule,
  7645. DWORD dwPermanentCardID,
  7646. DWORD dwNumberOfDigits,
  7647. DWORD dwOptions
  7648. )
  7649. {
  7650. HRESULT hr = S_OK;
  7651. LOG((TL_TRACE, "Initialize - enter" ));
  7652. Lock();
  7653. m_dwPermanentCardID = dwPermanentCardID;
  7654. m_dwNumberOfDigits = dwNumberOfDigits;
  7655. m_dwOptions = dwOptions;
  7656. m_szCardName = NULL;
  7657. m_szSameAreaDialingRule = NULL;
  7658. m_szLongDistanceDialingRule = NULL;
  7659. m_szInternationalDialingRule = NULL;
  7660. // copy the Card Name
  7661. if (pszCardName != NULL)
  7662. {
  7663. m_szCardName = (PWSTR) ClientAlloc((lstrlenW(pszCardName) + 1) * sizeof (WCHAR));
  7664. if (m_szCardName != NULL)
  7665. {
  7666. lstrcpyW(m_szCardName, pszCardName);
  7667. }
  7668. else
  7669. {
  7670. LOG((TL_ERROR, "Initialize - Alloc m_szCardName failed" ));
  7671. hr = E_OUTOFMEMORY;
  7672. }
  7673. }
  7674. // copy the Same Area Dialing Rule
  7675. if (pszSameAreaDialingRule != NULL)
  7676. {
  7677. m_szSameAreaDialingRule = (PWSTR) ClientAlloc((lstrlenW(pszSameAreaDialingRule) + 1) * sizeof (WCHAR));
  7678. if (m_szSameAreaDialingRule != NULL)
  7679. {
  7680. lstrcpyW(m_szSameAreaDialingRule, pszSameAreaDialingRule);
  7681. }
  7682. else
  7683. {
  7684. LOG((TL_ERROR, "Initialize - Alloc m_szSameAreaDialingRule failed" ));
  7685. hr = E_OUTOFMEMORY;
  7686. }
  7687. }
  7688. // copy the Long Distance Dialing Rule
  7689. if (pszLongDistanceDialingRule != NULL)
  7690. {
  7691. m_szLongDistanceDialingRule = (PWSTR) ClientAlloc((lstrlenW(pszLongDistanceDialingRule) + 1) * sizeof (WCHAR));
  7692. if (m_szLongDistanceDialingRule != NULL)
  7693. {
  7694. lstrcpyW(m_szLongDistanceDialingRule, pszLongDistanceDialingRule);
  7695. }
  7696. else
  7697. {
  7698. LOG((TL_ERROR, "Initialize - Alloc m_szLongDistanceDialingRule failed" ));
  7699. hr = E_OUTOFMEMORY;
  7700. }
  7701. }
  7702. //copy the International Dialing Rule
  7703. if (pszInternationalDialingRule != NULL)
  7704. {
  7705. m_szInternationalDialingRule = (PWSTR) ClientAlloc((lstrlenW(pszInternationalDialingRule) + 1) * sizeof (WCHAR));
  7706. if (m_szInternationalDialingRule != NULL)
  7707. {
  7708. lstrcpyW(m_szInternationalDialingRule, pszInternationalDialingRule);
  7709. }
  7710. else
  7711. {
  7712. LOG((TL_ERROR, "Initialize - Alloc m_szInternationalDialingRule failed" ));
  7713. hr = E_OUTOFMEMORY;
  7714. }
  7715. }
  7716. Unlock();
  7717. LOG((TL_TRACE, hr, "Initialize - exit" ));
  7718. return hr;
  7719. }
  7720. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7721. // Class : CCallingCard
  7722. // Method : FinalRelease
  7723. //
  7724. //
  7725. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7726. void CCallingCard::FinalRelease()
  7727. {
  7728. LOG((TL_TRACE, "FinalRelease - enter" ));
  7729. if (m_szCardName != NULL)
  7730. {
  7731. ClientFree(m_szCardName);
  7732. }
  7733. if (m_szSameAreaDialingRule != NULL)
  7734. {
  7735. ClientFree(m_szSameAreaDialingRule);
  7736. }
  7737. if (m_szLongDistanceDialingRule != NULL)
  7738. {
  7739. ClientFree(m_szLongDistanceDialingRule);
  7740. }
  7741. if (m_szInternationalDialingRule != NULL)
  7742. {
  7743. ClientFree(m_szInternationalDialingRule);
  7744. }
  7745. LOG((TL_TRACE, "FinalRelease - exit" ));
  7746. }
  7747. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7748. // Class : CCallingCard
  7749. // Interface : ITCallingCard
  7750. // Method : get_PermanentCardID
  7751. //
  7752. //
  7753. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7754. STDMETHODIMP
  7755. CCallingCard::get_PermanentCardID(long * ulCardID)
  7756. {
  7757. HRESULT hr = S_OK;
  7758. LOG((TL_TRACE, "get_PermanentCardID - enter" ));
  7759. Lock();
  7760. if ( TAPIIsBadWritePtr( ulCardID, sizeof(long) ) )
  7761. {
  7762. LOG((TL_ERROR, "get_PermanentCardID - Bad Pointer" ));
  7763. hr = E_POINTER;
  7764. }
  7765. else // Ok Pointer
  7766. {
  7767. *ulCardID= m_dwPermanentCardID;
  7768. }
  7769. Unlock();
  7770. LOG((TL_TRACE, hr, "get_PermanentCardID - exit" ));
  7771. return hr;
  7772. }
  7773. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7774. // Class : CCallingCard
  7775. // Interface : ITCallingCard
  7776. // Method : get_NumberOfDigits
  7777. //
  7778. //
  7779. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7780. STDMETHODIMP
  7781. CCallingCard::get_NumberOfDigits(long * ulDigits)
  7782. {
  7783. HRESULT hr = S_OK;
  7784. LOG((TL_TRACE, "get_NumberOfDigits - enter" ));
  7785. Lock();
  7786. if ( TAPIIsBadWritePtr( ulDigits, sizeof(long) ) )
  7787. {
  7788. LOG((TL_ERROR, "get_NumberOfDigits - Bad Pointer" ));
  7789. hr = E_POINTER;
  7790. }
  7791. else // Ok Pointer
  7792. {
  7793. *ulDigits= m_dwNumberOfDigits;
  7794. }
  7795. Unlock();
  7796. LOG((TL_TRACE, hr, "get_NumberOfDigits - exit" ));
  7797. return hr;
  7798. }
  7799. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7800. // Class : CCallingCard
  7801. // Interface : ITCallingCard
  7802. // Method : get_Options
  7803. //
  7804. //
  7805. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7806. STDMETHODIMP
  7807. CCallingCard::get_Options(long * ulOptions)
  7808. {
  7809. HRESULT hr = S_OK;
  7810. LOG((TL_TRACE, "get_Options - enter" ));
  7811. Lock();
  7812. if ( TAPIIsBadWritePtr( ulOptions, sizeof(long) ) )
  7813. {
  7814. LOG((TL_ERROR, "get_Options - Bad Pointer" ));
  7815. hr = E_POINTER;
  7816. }
  7817. else // Ok Pointer
  7818. {
  7819. *ulOptions= m_dwOptions;
  7820. }
  7821. Unlock();
  7822. LOG((TL_TRACE, hr, "get_Options - exit" ));
  7823. return hr;
  7824. }
  7825. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7826. // Class : CCallingCard
  7827. // Interface : ITCallingCard
  7828. // Method : get_CardName
  7829. //
  7830. //
  7831. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7832. STDMETHODIMP
  7833. CCallingCard::get_CardName(BSTR * ppCardName)
  7834. {
  7835. HRESULT hr = S_OK;
  7836. LOG((TL_TRACE, "get_CardName - enter" ));
  7837. Lock();
  7838. if ( TAPIIsBadWritePtr( ppCardName, sizeof(BSTR) ) )
  7839. {
  7840. LOG((TL_ERROR, "get_CardName - Bad Pointer" ));
  7841. hr = E_POINTER;
  7842. }
  7843. else // Ok Pointer
  7844. {
  7845. *ppCardName = SysAllocString( m_szCardName );
  7846. if ( ( NULL == *ppCardName ) && ( NULL != m_szCardName ) )
  7847. {
  7848. LOG((TL_TRACE, "SysAllocString Failed" ));
  7849. hr = E_OUTOFMEMORY;
  7850. }
  7851. }
  7852. Unlock();
  7853. LOG((TL_TRACE, hr, "get_CardName - exit" ));
  7854. return hr;
  7855. }
  7856. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7857. // Class : CCallingCard
  7858. // Interface : ITCallingCard
  7859. // Method : get_SameAreaDialingRule
  7860. //
  7861. //
  7862. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7863. STDMETHODIMP
  7864. CCallingCard::get_SameAreaDialingRule(BSTR * ppRule)
  7865. {
  7866. HRESULT hr = S_OK;
  7867. LOG((TL_TRACE, "get_SameAreaDialingRule - enter" ));
  7868. Lock();
  7869. if ( TAPIIsBadWritePtr( ppRule, sizeof(BSTR) ) )
  7870. {
  7871. LOG((TL_ERROR, "get_SameAreaDialingRule - Bad Pointer" ));
  7872. hr = E_POINTER;
  7873. }
  7874. else // Ok Pointer
  7875. {
  7876. *ppRule = SysAllocString( m_szSameAreaDialingRule );
  7877. if ( ( NULL == *ppRule ) && ( NULL != m_szSameAreaDialingRule ) )
  7878. {
  7879. LOG((TL_TRACE, "SysAllocString Failed" ));
  7880. hr = E_OUTOFMEMORY;
  7881. }
  7882. }
  7883. Unlock();
  7884. LOG((TL_TRACE, hr, "get_SameAreaDialingRule - exit" ));
  7885. return hr;
  7886. }
  7887. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7888. // Class : CCallingCard
  7889. // Interface : ITCallingCard
  7890. // Method : get_LongDistanceDialingRule
  7891. //
  7892. //
  7893. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7894. STDMETHODIMP
  7895. CCallingCard::get_LongDistanceDialingRule(BSTR * ppRule)
  7896. {
  7897. HRESULT hr = S_OK;
  7898. LOG((TL_TRACE, "get_LongDistanceDialingRule - enter" ));
  7899. Lock();
  7900. if ( TAPIIsBadWritePtr( ppRule, sizeof(BSTR) ) )
  7901. {
  7902. LOG((TL_ERROR, "get_LongDistanceDialingRule - Bad Pointer" ));
  7903. hr = E_POINTER;
  7904. }
  7905. else // Ok Pointer
  7906. {
  7907. *ppRule = SysAllocString( m_szLongDistanceDialingRule );
  7908. if ( ( NULL == *ppRule ) && ( NULL != m_szLongDistanceDialingRule ) )
  7909. {
  7910. LOG((TL_TRACE, "SysAllocString Failed" ));
  7911. hr = E_OUTOFMEMORY;
  7912. }
  7913. }
  7914. Unlock();
  7915. LOG((TL_TRACE, hr, "get_LongDistanceDialingRule - exit" ));
  7916. return hr;
  7917. }
  7918. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7919. // Class : CCallingCard
  7920. // Interface : ITCallingCard
  7921. // Method : get_InternationalDialingRule
  7922. //
  7923. //
  7924. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7925. STDMETHODIMP
  7926. CCallingCard::get_InternationalDialingRule(BSTR * ppRule)
  7927. {
  7928. HRESULT hr = S_OK;
  7929. LOG((TL_TRACE, "get_InternationalDialingRule - enter" ));
  7930. Lock();
  7931. if ( TAPIIsBadWritePtr( ppRule, sizeof(BSTR) ) )
  7932. {
  7933. LOG((TL_ERROR, "get_InternationalDialingRule - Bad Pointer" ));
  7934. hr = E_POINTER;
  7935. }
  7936. else // Ok Pointer
  7937. {
  7938. *ppRule = SysAllocString( m_szInternationalDialingRule );
  7939. if ( ( NULL == *ppRule ) && ( NULL != m_szInternationalDialingRule ) )
  7940. {
  7941. LOG((TL_TRACE, "SysAllocString Failed" ));
  7942. hr = E_OUTOFMEMORY;
  7943. }
  7944. }
  7945. Unlock();
  7946. LOG((TL_TRACE, hr, "get_InternationalDialingRule - exit" ));
  7947. return hr;
  7948. }
  7949. //
  7950. // ----------------------- CLocationInfo -----------------------------
  7951. //
  7952. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7953. // Class : CLocationInfo
  7954. // Method : Initialize
  7955. //
  7956. //
  7957. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7958. HRESULT
  7959. CLocationInfo::Initialize(
  7960. PWSTR pszLocationName,
  7961. PWSTR pszCityCode,
  7962. PWSTR pszLocalAccessCode,
  7963. PWSTR pszLongDistanceAccessCode,
  7964. PWSTR pszTollPrefixList,
  7965. PWSTR pszCancelCallWaitingCode ,
  7966. DWORD dwPermanentLocationID,
  7967. DWORD dwCountryCode,
  7968. DWORD dwPreferredCardID,
  7969. DWORD dwCountryID,
  7970. DWORD dwOptions
  7971. )
  7972. {
  7973. HRESULT hr = S_OK;
  7974. LOG((TL_TRACE, "Initialize - enter" ));
  7975. Lock();
  7976. m_dwPermanentLocationID = dwPermanentLocationID;
  7977. m_dwCountryCode = dwCountryCode;
  7978. m_dwPreferredCardID = dwPreferredCardID;
  7979. m_dwCountryID = dwCountryID;
  7980. m_dwOptions = dwOptions;
  7981. m_szLocationName = NULL;
  7982. m_szCityCode = NULL;
  7983. m_szLocalAccessCode = NULL;
  7984. m_szLongDistanceAccessCode = NULL;
  7985. m_szTollPrefixList = NULL;
  7986. m_szCancelCallWaitingCode = NULL;
  7987. // copy the Location Name
  7988. if (pszLocationName!= NULL)
  7989. {
  7990. m_szLocationName = (PWSTR) ClientAlloc((lstrlenW(pszLocationName) + 1) * sizeof (WCHAR));
  7991. if (m_szLocationName != NULL)
  7992. {
  7993. lstrcpyW(m_szLocationName, pszLocationName);
  7994. }
  7995. else
  7996. {
  7997. LOG((TL_ERROR, "Initialize - Alloc m_szDialableString failed" ));
  7998. hr = E_OUTOFMEMORY;
  7999. }
  8000. }
  8001. // copy the City Code
  8002. if (pszCityCode != NULL)
  8003. {
  8004. m_szCityCode = (PWSTR) ClientAlloc((lstrlenW(pszCityCode) + 1) * sizeof (WCHAR));
  8005. if (m_szCityCode != NULL)
  8006. {
  8007. lstrcpyW(m_szCityCode , pszCityCode);
  8008. }
  8009. else
  8010. {
  8011. LOG((TL_ERROR, "Initialize - Alloc m_szCityCode failed" ));
  8012. hr = E_OUTOFMEMORY;
  8013. }
  8014. }
  8015. // copy the Local Access Code
  8016. if (pszLocalAccessCode != NULL)
  8017. {
  8018. m_szLocalAccessCode = (PWSTR) ClientAlloc((lstrlenW(pszLocalAccessCode) + 1) * sizeof (WCHAR));
  8019. if (m_szLocalAccessCode != NULL)
  8020. {
  8021. lstrcpyW(m_szLocalAccessCode, pszLocalAccessCode);
  8022. }
  8023. else
  8024. {
  8025. LOG((TL_ERROR, "Initialize - Alloc m_szLocalAccessCode failed" ));
  8026. hr = E_OUTOFMEMORY;
  8027. }
  8028. }
  8029. // copy the Long Distance Access Code
  8030. if (pszLongDistanceAccessCode != NULL)
  8031. {
  8032. m_szLongDistanceAccessCode = (PWSTR) ClientAlloc((lstrlenW(pszLongDistanceAccessCode) + 1) * sizeof (WCHAR));
  8033. if (m_szLongDistanceAccessCode != NULL)
  8034. {
  8035. lstrcpyW(m_szLongDistanceAccessCode, pszLongDistanceAccessCode);
  8036. }
  8037. else
  8038. {
  8039. LOG((TL_ERROR, "Initialize - Alloc m_szLongDistanceAccessCode failed" ));
  8040. hr = E_OUTOFMEMORY;
  8041. }
  8042. }
  8043. // copy the Toll Prefix List
  8044. if (pszTollPrefixList != NULL)
  8045. {
  8046. m_szTollPrefixList = (PWSTR) ClientAlloc((lstrlenW(pszTollPrefixList) + 1) * sizeof (WCHAR));
  8047. if (m_szTollPrefixList != NULL)
  8048. {
  8049. lstrcpyW(m_szTollPrefixList, pszTollPrefixList);
  8050. }
  8051. else
  8052. {
  8053. LOG((TL_ERROR, "Initialize - Alloc m_szTollPrefixList failed" ));
  8054. hr = E_OUTOFMEMORY;
  8055. }
  8056. }
  8057. // copy the Cancel Call Waiting Code
  8058. if (pszCancelCallWaitingCode != NULL)
  8059. {
  8060. m_szCancelCallWaitingCode = (PWSTR) ClientAlloc((lstrlenW(pszCancelCallWaitingCode) + 1) * sizeof (WCHAR));
  8061. if (m_szCancelCallWaitingCode != NULL)
  8062. {
  8063. lstrcpyW(m_szCancelCallWaitingCode, pszCancelCallWaitingCode);
  8064. }
  8065. else
  8066. {
  8067. LOG((TL_ERROR, "Initialize - Alloc m_szCancelCallWaitingCode failed" ));
  8068. hr = E_OUTOFMEMORY;
  8069. }
  8070. }
  8071. Unlock();
  8072. LOG((TL_TRACE, hr, "Initialize - exit" ));
  8073. return hr;
  8074. }
  8075. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8076. // Class : CLocationInfo
  8077. // Method : FinalRelease
  8078. //
  8079. //
  8080. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8081. void CLocationInfo::FinalRelease()
  8082. {
  8083. LOG((TL_TRACE, "FinalRelease - enter" ));
  8084. if (m_szLocationName != NULL)
  8085. {
  8086. ClientFree( m_szLocationName);
  8087. }
  8088. if (m_szCityCode != NULL)
  8089. {
  8090. ClientFree( m_szCityCode);
  8091. }
  8092. if (m_szLocalAccessCode != NULL)
  8093. {
  8094. ClientFree( m_szLocalAccessCode);
  8095. }
  8096. if (m_szLongDistanceAccessCode != NULL)
  8097. {
  8098. ClientFree( m_szLongDistanceAccessCode);
  8099. }
  8100. if (m_szTollPrefixList != NULL)
  8101. {
  8102. ClientFree( m_szTollPrefixList);
  8103. }
  8104. if (m_szCancelCallWaitingCode != NULL)
  8105. {
  8106. ClientFree( m_szCancelCallWaitingCode);
  8107. }
  8108. LOG((TL_TRACE, "FinalRelease - exit" ));
  8109. }
  8110. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8111. // Class : CLocationInfo
  8112. // Interface : ITLocationInfo
  8113. // Method : get_PermanentLocationID
  8114. //
  8115. //
  8116. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8117. STDMETHODIMP
  8118. CLocationInfo::get_PermanentLocationID(long * ulLocationID )
  8119. {
  8120. HRESULT hr = S_OK;
  8121. LOG((TL_TRACE, "get_PermanentLocationID - enter" ));
  8122. Lock();
  8123. if ( TAPIIsBadWritePtr( ulLocationID , sizeof(long) ) )
  8124. {
  8125. LOG((TL_ERROR, "get_PermanentLocationID - Bad Pointer" ));
  8126. hr = E_POINTER;
  8127. }
  8128. else // Ok Pointer
  8129. {
  8130. *ulLocationID = m_dwPermanentLocationID;
  8131. }
  8132. Unlock();
  8133. LOG((TL_TRACE, hr, "get_PermanentLocationID - exit" ));
  8134. return hr;
  8135. }
  8136. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8137. // Class : CLocationInfo
  8138. // Interface : ITLocationInfo
  8139. // Method : get_CountryCode
  8140. //
  8141. //
  8142. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8143. STDMETHODIMP
  8144. CLocationInfo::get_CountryCode(long * ulCountryCode)
  8145. {
  8146. HRESULT hr = S_OK;
  8147. LOG((TL_TRACE, "get_CountryCode - enter" ));
  8148. Lock();
  8149. if ( TAPIIsBadWritePtr( ulCountryCode, sizeof(long) ) )
  8150. {
  8151. LOG((TL_ERROR, "get_CountryCode - Bad Pointer" ));
  8152. hr = E_POINTER;
  8153. }
  8154. else // Ok Pointer
  8155. {
  8156. *ulCountryCode= m_dwCountryCode;
  8157. }
  8158. Unlock();
  8159. LOG((TL_TRACE, hr, "get_CountryCode - exit" ));
  8160. return hr;
  8161. }
  8162. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8163. // Class : CLocationInfo
  8164. // Interface : ITLocationInfo
  8165. // Method : get_CountryID
  8166. //
  8167. //
  8168. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8169. STDMETHODIMP
  8170. CLocationInfo::get_CountryID(long * ulCountryID)
  8171. {
  8172. HRESULT hr = S_OK;
  8173. LOG((TL_TRACE, "get_CountryID - enter" ));
  8174. Lock();
  8175. if ( TAPIIsBadWritePtr( ulCountryID, sizeof(long) ) )
  8176. {
  8177. LOG((TL_ERROR, "get_CountryID - Bad Pointer" ));
  8178. hr = E_POINTER;
  8179. }
  8180. else // Ok Pointer
  8181. {
  8182. *ulCountryID= m_dwCountryID;
  8183. }
  8184. Unlock();
  8185. LOG((TL_TRACE, hr, "get_CountryID - exit" ));
  8186. return hr;
  8187. }
  8188. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8189. // Class : CLocationInfo
  8190. // Interface : ITLocationInfo
  8191. // Method : get_Options
  8192. //
  8193. //
  8194. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8195. STDMETHODIMP
  8196. CLocationInfo::get_Options(long * Options)
  8197. {
  8198. HRESULT hr = S_OK;
  8199. LOG((TL_TRACE, "get_Options - enter" ));
  8200. Lock();
  8201. if ( TAPIIsBadWritePtr( Options, sizeof(long) ) )
  8202. {
  8203. LOG((TL_ERROR, "get_Options - Bad Pointer" ));
  8204. hr = E_POINTER;
  8205. }
  8206. else // Ok Pointer
  8207. {
  8208. *Options= m_dwOptions;
  8209. }
  8210. Unlock();
  8211. LOG((TL_TRACE, hr, "get_Options - exit" ));
  8212. return hr;
  8213. }
  8214. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8215. // Class : CLocationInfo
  8216. // Interface : ITLocationInfo
  8217. // Method : get_PreferredCardID
  8218. //
  8219. //
  8220. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8221. STDMETHODIMP
  8222. CLocationInfo::get_PreferredCardID(long * ulCardID)
  8223. {
  8224. HRESULT hr = S_OK;
  8225. LOG((TL_TRACE, "get_PreferredCardID - enter" ));
  8226. Lock();
  8227. if ( TAPIIsBadWritePtr( ulCardID, sizeof(long) ) )
  8228. {
  8229. LOG((TL_ERROR, "get_PreferredCardID - Bad Pointer" ));
  8230. hr = E_POINTER;
  8231. }
  8232. else // Ok Pointer
  8233. {
  8234. *ulCardID= m_dwPreferredCardID;
  8235. }
  8236. Unlock();
  8237. LOG((TL_TRACE, hr, "get_PreferredCardID - exit" ));
  8238. return hr;
  8239. }
  8240. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8241. // Class : CLocationInfo
  8242. // Interface : ITLocationInfo
  8243. // Method : get_LocationName
  8244. //
  8245. //
  8246. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8247. STDMETHODIMP
  8248. CLocationInfo::get_LocationName(BSTR * ppLocationName)
  8249. {
  8250. HRESULT hr = S_OK;
  8251. LOG((TL_TRACE, "get_LocationName - enter" ));
  8252. Lock();
  8253. if ( TAPIIsBadWritePtr( ppLocationName, sizeof(BSTR) ) )
  8254. {
  8255. LOG((TL_ERROR, "get_LocationName - Bad Pointer" ));
  8256. hr = E_POINTER;
  8257. }
  8258. else // Ok Pointer
  8259. {
  8260. *ppLocationName = SysAllocString( m_szLocationName );
  8261. if ( ( NULL == *ppLocationName ) && ( NULL != m_szLocationName ) )
  8262. {
  8263. LOG((TL_TRACE, "SysAllocString Failed" ));
  8264. hr = E_OUTOFMEMORY;
  8265. }
  8266. }
  8267. Unlock();
  8268. LOG((TL_TRACE, hr, "gget_LocationName - exit" ));
  8269. return hr;
  8270. }
  8271. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8272. // Class : CLocationInfo
  8273. // Interface : ITLocationInfo
  8274. // Method : get_CityCode
  8275. //
  8276. //
  8277. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8278. STDMETHODIMP
  8279. CLocationInfo::get_CityCode(BSTR * ppCode)
  8280. {
  8281. HRESULT hr = S_OK;
  8282. LOG((TL_TRACE, "get_CityCode - enter" ));
  8283. Lock();
  8284. if ( TAPIIsBadWritePtr( ppCode, sizeof(BSTR) ) )
  8285. {
  8286. LOG((TL_ERROR, "get_CityCode - Bad Pointer" ));
  8287. hr = E_POINTER;
  8288. }
  8289. else // Ok Pointer
  8290. {
  8291. *ppCode = SysAllocString( m_szCityCode );
  8292. if ( ( NULL == *ppCode ) && ( NULL != m_szCityCode ) )
  8293. {
  8294. LOG((TL_TRACE, "SysAllocString Failed" ));
  8295. hr = E_OUTOFMEMORY;
  8296. }
  8297. }
  8298. Unlock();
  8299. LOG((TL_TRACE, hr, "get_CityCode - exit" ));
  8300. return hr;
  8301. }
  8302. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8303. // Class : CLocationInfo
  8304. // Interface : ITLocationInfo
  8305. // Method : get_LocalAccessCode
  8306. //
  8307. //
  8308. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8309. STDMETHODIMP
  8310. CLocationInfo::get_LocalAccessCode(BSTR * ppCode)
  8311. {
  8312. HRESULT hr = S_OK;
  8313. LOG((TL_TRACE, "get_LocalAccessCode - enter" ));
  8314. Lock();
  8315. if ( TAPIIsBadWritePtr( ppCode, sizeof(BSTR) ) )
  8316. {
  8317. LOG((TL_ERROR, "get_LocalAccessCode - Bad Pointer" ));
  8318. hr = E_POINTER;
  8319. }
  8320. else // Ok Pointer
  8321. {
  8322. *ppCode = SysAllocString( m_szLocalAccessCode );
  8323. if ( ( NULL == *ppCode ) && ( NULL != m_szLocalAccessCode ) )
  8324. {
  8325. LOG((TL_TRACE, "SysAllocString Failed" ));
  8326. hr = E_OUTOFMEMORY;
  8327. }
  8328. }
  8329. Unlock();
  8330. LOG((TL_TRACE, hr, "get_LocalAccessCode - exit" ));
  8331. return hr;
  8332. }
  8333. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8334. // Class : CLocationInfo
  8335. // Interface : ITLocationInfo
  8336. // Method : get_LongDistanceAccessCode
  8337. //
  8338. //
  8339. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8340. STDMETHODIMP
  8341. CLocationInfo::get_LongDistanceAccessCode(BSTR * ppCode )
  8342. {
  8343. HRESULT hr = S_OK;
  8344. LOG((TL_TRACE, "get_LongDistanceAccessCode - enter" ));
  8345. Lock();
  8346. if ( TAPIIsBadWritePtr( ppCode , sizeof(BSTR) ) )
  8347. {
  8348. LOG((TL_ERROR, "get_LongDistanceAccessCode - Bad Pointer" ));
  8349. hr = E_POINTER;
  8350. }
  8351. else // Ok Pointer
  8352. {
  8353. *ppCode = SysAllocString( m_szLongDistanceAccessCode);
  8354. if ( ( NULL == *ppCode ) && ( NULL != m_szLongDistanceAccessCode ) )
  8355. {
  8356. LOG((TL_TRACE, "SysAllocString Failed" ));
  8357. hr = E_OUTOFMEMORY;
  8358. }
  8359. }
  8360. Unlock();
  8361. LOG((TL_TRACE, hr, "get_LongDistanceAccessCode - exit" ));
  8362. return hr;
  8363. }
  8364. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8365. // Class : CLocationInfo
  8366. // Interface : ITLocationInfo
  8367. // Method : get_TollPrefixList
  8368. //
  8369. //
  8370. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8371. STDMETHODIMP
  8372. CLocationInfo::get_TollPrefixList(BSTR * ppTollList)
  8373. {
  8374. HRESULT hr = S_OK;
  8375. LOG((TL_TRACE, "get_TollPrefixList - enter" ));
  8376. Lock();
  8377. if ( TAPIIsBadWritePtr( ppTollList, sizeof(BSTR) ) )
  8378. {
  8379. LOG((TL_ERROR, "get_TollPrefixList - Bad Pointer" ));
  8380. hr = E_POINTER;
  8381. }
  8382. else // Ok Pointer
  8383. {
  8384. *ppTollList = SysAllocString( m_szTollPrefixList );
  8385. if ( ( NULL == *ppTollList ) && ( NULL != m_szTollPrefixList ) )
  8386. {
  8387. LOG((TL_TRACE, "SysAllocString Failed" ));
  8388. hr = E_OUTOFMEMORY;
  8389. }
  8390. }
  8391. Unlock();
  8392. LOG((TL_TRACE, hr, "get_TollPrefixList - exit" ));
  8393. return hr;
  8394. }
  8395. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8396. // Class : CLocationInfo
  8397. // Interface : ITLocationInfo
  8398. // Method : get_CancelCallWaitingCode
  8399. //
  8400. //
  8401. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8402. STDMETHODIMP
  8403. CLocationInfo::get_CancelCallWaitingCode(BSTR * ppCode)
  8404. {
  8405. HRESULT hr = S_OK;
  8406. LOG((TL_TRACE, "get_CancelCallWaitingCode - enter" ));
  8407. Lock();
  8408. if ( TAPIIsBadWritePtr( ppCode, sizeof(BSTR) ) )
  8409. {
  8410. LOG((TL_ERROR, "get_CancelCallWaitingCode - Bad Pointer" ));
  8411. hr = E_POINTER;
  8412. }
  8413. else // Ok Pointer
  8414. {
  8415. *ppCode = SysAllocString( m_szCancelCallWaitingCode );
  8416. if ( ( NULL == *ppCode ) && ( NULL != m_szCancelCallWaitingCode ) )
  8417. {
  8418. LOG((TL_TRACE, "SysAllocString Failed" ));
  8419. hr = E_OUTOFMEMORY;
  8420. }
  8421. }
  8422. Unlock();
  8423. LOG((TL_TRACE, hr, "get_CancelCallWaitingCode - exit" ));
  8424. return hr;
  8425. }
  8426. BOOL
  8427. CAddress::GetMediaMode( long lMediaType, DWORD * pdwMediaMode )
  8428. {
  8429. DWORD dwRet = (DWORD)lMediaType;
  8430. DWORD dwHold;
  8431. if (dwRet & AUDIOMEDIAMODES)
  8432. {
  8433. dwHold = m_dwMediaModesSupported & AUDIOMEDIAMODES;
  8434. if ( dwHold == AUDIOMEDIAMODES )
  8435. {
  8436. dwHold = LINEMEDIAMODE_AUTOMATEDVOICE;
  8437. }
  8438. dwRet &= ~AUDIOMEDIAMODES;
  8439. dwRet |= dwHold;
  8440. }
  8441. *pdwMediaMode = dwRet;
  8442. if ( (dwRet == 0) ||
  8443. ((dwRet & m_dwMediaModesSupported) != dwRet) )
  8444. {
  8445. return FALSE;
  8446. }
  8447. return TRUE;
  8448. }
  8449. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8450. //
  8451. // get_LineID
  8452. //
  8453. // returns the tapi 2 device ID for this line
  8454. //
  8455. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8456. STDMETHODIMP
  8457. CAddress::get_LineID(
  8458. long * plLineID
  8459. )
  8460. {
  8461. LOG((TL_TRACE, "get_LineID - enter"));
  8462. if ( TAPIIsBadWritePtr( plLineID, sizeof(long) ) )
  8463. {
  8464. LOG((TL_ERROR, "get_LineID - bad pointer"));
  8465. return E_POINTER;
  8466. }
  8467. Lock();
  8468. *plLineID = m_dwDeviceID;
  8469. Unlock();
  8470. LOG((TL_TRACE, "get_LineID - exit"));
  8471. return S_OK;
  8472. }
  8473. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8474. //
  8475. // get_AddressID
  8476. //
  8477. // returns the tapi 2 address ID of this address
  8478. //
  8479. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8480. STDMETHODIMP
  8481. CAddress::get_AddressID(
  8482. long * plAddressID
  8483. )
  8484. {
  8485. LOG((TL_TRACE, "get_AddressID - enter"));
  8486. if ( TAPIIsBadWritePtr( plAddressID, sizeof(long) ) )
  8487. {
  8488. LOG((TL_ERROR, "get_AddressID - bad pointer"));
  8489. return E_POINTER;
  8490. }
  8491. Lock();
  8492. *plAddressID = m_dwAddressID;
  8493. Unlock();
  8494. LOG((TL_TRACE, "get_AddressID - exit"));
  8495. return S_OK;
  8496. }
  8497. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8498. //
  8499. // CAddress::UpdateAddressCaps
  8500. //
  8501. // must be called in lock
  8502. //
  8503. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8504. HRESULT
  8505. CAddress::UpdateAddressCaps()
  8506. {
  8507. HRESULT hr = S_OK;
  8508. if ( NULL == m_pAddressCaps )
  8509. {
  8510. LPLINEADDRESSCAPS pTemp;
  8511. CTAPI * pCTapi;
  8512. pCTapi = GetTapi();
  8513. if( NULL == pCTapi )
  8514. {
  8515. LOG((TL_ERROR, "dynamic cast operation failed"));
  8516. hr = E_POINTER;
  8517. }
  8518. else
  8519. {
  8520. hr = pCTapi->GetBuffer( BUFFERTYPE_ADDRCAP,
  8521. (UINT_PTR)this,
  8522. (LPVOID*)&m_pAddressCaps
  8523. );
  8524. }
  8525. if ( !SUCCEEDED(hr) )
  8526. {
  8527. return hr;
  8528. }
  8529. pTemp = m_pAddressCaps;
  8530. hr = LineGetAddressCaps(
  8531. m_hLineApp,
  8532. m_dwDeviceID,
  8533. m_dwAddressID,
  8534. m_dwAPIVersion,
  8535. &m_pAddressCaps
  8536. );
  8537. if ( !SUCCEEDED(hr) )
  8538. {
  8539. return hr;
  8540. }
  8541. if ( m_pAddressCaps != pTemp )
  8542. {
  8543. pCTapi->SetBuffer( BUFFERTYPE_ADDRCAP, (UINT_PTR)this, (LPVOID)m_pAddressCaps );
  8544. }
  8545. }
  8546. return S_OK;
  8547. }
  8548. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8549. //
  8550. // CAddress::UpdateLineDevCaps
  8551. //
  8552. // must be called in lock
  8553. //
  8554. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8555. HRESULT
  8556. CAddress::UpdateLineDevCaps()
  8557. {
  8558. HRESULT hr = S_OK;
  8559. if ( NULL == m_pDevCaps )
  8560. {
  8561. LPLINEDEVCAPS pTemp;
  8562. CTAPI * pCTapi;
  8563. pCTapi = GetTapi();
  8564. if( NULL == pCTapi )
  8565. {
  8566. LOG((TL_ERROR, "dynamic cast operation failed"));
  8567. hr = E_POINTER;
  8568. }
  8569. else
  8570. {
  8571. hr = pCTapi->GetBuffer( BUFFERTYPE_LINEDEVCAP,
  8572. (UINT_PTR)this,
  8573. (LPVOID*)&m_pDevCaps
  8574. );
  8575. }
  8576. if ( !SUCCEEDED(hr) )
  8577. {
  8578. return hr;
  8579. }
  8580. pTemp = m_pDevCaps;
  8581. hr = LineGetDevCaps(
  8582. m_hLineApp,
  8583. m_dwDeviceID,
  8584. m_dwAPIVersion,
  8585. &m_pDevCaps
  8586. );
  8587. if ( !SUCCEEDED(hr) )
  8588. {
  8589. return hr;
  8590. }
  8591. if ( m_pDevCaps != pTemp )
  8592. {
  8593. pCTapi->SetBuffer( BUFFERTYPE_LINEDEVCAP, (UINT_PTR)this, (LPVOID)m_pDevCaps );
  8594. }
  8595. }
  8596. return S_OK;
  8597. }
  8598. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8599. //
  8600. // SetAddrCapBuffer
  8601. //
  8602. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8603. void
  8604. CAddress::SetAddrCapBuffer( LPVOID pBuf )
  8605. {
  8606. Lock();
  8607. m_pAddressCaps = (LPLINEADDRESSCAPS)pBuf;
  8608. Unlock();
  8609. }
  8610. void
  8611. CAddress::SetLineDevCapBuffer( LPVOID pBuf )
  8612. {
  8613. Lock();
  8614. m_pDevCaps = (LPLINEDEVCAPS)pBuf;
  8615. Unlock();
  8616. }
  8617. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8618. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8619. HRESULT
  8620. CAddress::CreateMSPCall(
  8621. MSP_HANDLE hCall,
  8622. DWORD dwReserved,
  8623. long lMediaType,
  8624. IUnknown * pOuterUnk,
  8625. IUnknown ** ppStreamControl
  8626. )
  8627. {
  8628. HRESULT hr = E_FAIL;
  8629. if ( NULL != m_pMSPAggAddress )
  8630. {
  8631. ITMSPAddress * pMSPAddress = GetMSPAddress();
  8632. __try
  8633. {
  8634. hr = pMSPAddress->CreateMSPCall(
  8635. hCall,
  8636. dwReserved,
  8637. lMediaType,
  8638. pOuterUnk,
  8639. ppStreamControl
  8640. );
  8641. }
  8642. __except(EXCEPTION_EXECUTE_HANDLER)
  8643. {
  8644. //
  8645. // catch any exceptions thrown by the msp, to protect ouirselves from
  8646. // misbehaving msps
  8647. //
  8648. LOG((TL_ERROR,
  8649. "CreateMSPCall - MSPAddress::CreateMSPCall threw an exception"));
  8650. hr = E_OUTOFMEMORY;
  8651. }
  8652. pMSPAddress->Release();
  8653. }
  8654. return hr;
  8655. }
  8656. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8657. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8658. HRESULT
  8659. CAddress::ShutdownMSPCall( IUnknown * pStreamControl )
  8660. {
  8661. HRESULT hr = S_FALSE;
  8662. if ( NULL != m_pMSPAggAddress )
  8663. {
  8664. ITMSPAddress * pMSPAddress = GetMSPAddress();
  8665. hr = pMSPAddress->ShutdownMSPCall( pStreamControl );
  8666. pMSPAddress->Release();
  8667. }
  8668. return hr;
  8669. }
  8670. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8671. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8672. HRESULT
  8673. CAddress::ReceiveTSPData(
  8674. IUnknown * pMSPCall,
  8675. LPBYTE pBuffer,
  8676. DWORD dwSize
  8677. )
  8678. {
  8679. HRESULT hr = E_FAIL;
  8680. Lock();
  8681. if ( NULL != m_pMSPAggAddress )
  8682. {
  8683. ITMSPAddress * pMSPAddress = GetMSPAddress();
  8684. hr = pMSPAddress->ReceiveTSPData(
  8685. pMSPCall,
  8686. pBuffer,
  8687. dwSize
  8688. );
  8689. pMSPAddress->Release();
  8690. }
  8691. Unlock();
  8692. return hr;
  8693. }
  8694. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  8695. //
  8696. // LINE_SENDMSPMESSAGE handler
  8697. //
  8698. // give the opaque blob to the msp
  8699. //
  8700. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  8701. HRESULT HandleSendMSPDataMessage( PASYNCEVENTMSG pParams )
  8702. {
  8703. CAddress * pAddress;
  8704. BOOL bSuccess;
  8705. HRESULT hr = S_OK;
  8706. IUnknown * pMSPCall = NULL;;
  8707. LOG((TL_TRACE, "HandleSendMSPDataMessage - enter"));
  8708. //
  8709. // find the correct line
  8710. //
  8711. bSuccess = FindAddressObject(
  8712. (HLINE)(pParams->hDevice),
  8713. &pAddress
  8714. );
  8715. if (bSuccess)
  8716. {
  8717. CCall * pCall = NULL;
  8718. if ( NULL != (HCALL)(pParams->Param1) )
  8719. {
  8720. bSuccess = FindCallObject(
  8721. (HCALL)(pParams->Param1),
  8722. &pCall
  8723. );
  8724. if ( !bSuccess )
  8725. {
  8726. LOG((TL_ERROR, "HandleSendMSPDataMessage - couldn't find call %X",pParams->Param1));
  8727. //FindAddressObject addrefs the address objct
  8728. pAddress->Release();
  8729. return E_FAIL;
  8730. }
  8731. pMSPCall = pCall->GetMSPCall();
  8732. }
  8733. //
  8734. // the blob is at the end of the fixed
  8735. // structure
  8736. //
  8737. //
  8738. // get the size of the blob
  8739. //
  8740. DWORD dwSize = pParams->Param2;
  8741. BYTE *pBuffer = NULL;
  8742. //
  8743. // if the buffer's not empty, get a pointer to it
  8744. //
  8745. if (0 < dwSize)
  8746. {
  8747. pBuffer = (LPBYTE)(pParams + 1);
  8748. }
  8749. //
  8750. // call the msp
  8751. //
  8752. pAddress->ReceiveTSPData(
  8753. pMSPCall,
  8754. pBuffer,
  8755. dwSize
  8756. );
  8757. if ( pCall )
  8758. {
  8759. pCall->Release();
  8760. if ( pMSPCall )
  8761. {
  8762. pMSPCall->Release();
  8763. }
  8764. }
  8765. hr = S_OK;
  8766. //FindAddressObject addrefs the address objct
  8767. pAddress->Release();
  8768. }
  8769. else
  8770. {
  8771. LOG((TL_ERROR, "HandleSendMSPDataMessage - failed to find address Object %lx",
  8772. pParams->hDevice));
  8773. hr = E_FAIL;
  8774. }
  8775. LOG((TL_TRACE, "HandleSendMSPDataMessage - exit. hr = %lx", hr));
  8776. return hr;
  8777. }
  8778. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  8779. //
  8780. // HandleSendTSPData
  8781. //
  8782. // sends an opaque buffer from the msp to the tsp
  8783. //
  8784. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  8785. HRESULT
  8786. CAddress::HandleSendTSPData( MSP_EVENT_INFO * pEvent )
  8787. {
  8788. LOG((TL_INFO, "HandleSendTSPData - enter pEvent %p", pEvent));
  8789. //
  8790. // see if the event is bad
  8791. //
  8792. if (IsBadReadPtr(pEvent, sizeof(MSP_EVENT_INFO) ) )
  8793. {
  8794. LOG((TL_ERROR, "HandleSendTSPData - bad event structure"));
  8795. return E_POINTER;
  8796. }
  8797. HRESULT hr = S_OK;
  8798. HCALL hCall = NULL;
  8799. CCall * pCall = NULL;
  8800. AddressLineStruct * pAddressLine = NULL;
  8801. //
  8802. // if we were given msp call handle, find the corresponding call
  8803. //
  8804. if ( NULL != pEvent->hCall)
  8805. {
  8806. gpHandleHashTable->Lock();
  8807. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  8808. if ( SUCCEEDED(hr) )
  8809. {
  8810. //
  8811. // found the call, addreff the call and and release the table
  8812. //
  8813. LOG((TL_INFO, "HandleSendTSPData - Matched handle %X to Call object %p",
  8814. pEvent->hCall, pCall ));
  8815. pCall->AddRef();
  8816. gpHandleHashTable->Unlock();
  8817. //
  8818. // get the handle for this call
  8819. //
  8820. hCall = pCall->GetHCall();
  8821. //
  8822. // get call's address line, if any
  8823. //
  8824. pAddressLine = pCall->GetAddRefMyAddressLine();
  8825. LOG((TL_INFO, "HandleSendTSPData - address line[%p] hCall[%lx]",
  8826. pAddressLine, hCall ));
  8827. }
  8828. else
  8829. {
  8830. //
  8831. // there is no corresponding call in the hash table. the call no
  8832. // longer exists, or msp passed a bugus handle
  8833. //
  8834. gpHandleHashTable->Unlock();
  8835. LOG((TL_ERROR,
  8836. "HandleSendTSPData - Couldn't match handle %X to Call object. hr = %lx",
  8837. pEvent->hCall, hr));
  8838. return hr;
  8839. }
  8840. }
  8841. //
  8842. // by this point we either had msp call handle that is null or successfully
  8843. // found a matching call object and asked it for its address line
  8844. //
  8845. if (NULL == pAddressLine)
  8846. {
  8847. //
  8848. // if we don't have address line, send a message to the first address line on
  8849. // this address (?)
  8850. //
  8851. if ( m_AddressLinesPtrList.size() > 0 )
  8852. {
  8853. PtrList::iterator iter;
  8854. iter = m_AddressLinesPtrList.begin();
  8855. //
  8856. // send to the tsp
  8857. //
  8858. hr = LineReceiveMSPData(
  8859. ((AddressLineStruct *)(*iter))->t3Line.hLine,
  8860. hCall,
  8861. pEvent->MSP_TSP_DATA.pBuffer,
  8862. pEvent->MSP_TSP_DATA.dwBufferSize
  8863. );
  8864. }
  8865. else
  8866. {
  8867. LOG((TL_ERROR,
  8868. "HandleSendTSPData - no address lines on the address. E_UNEXPECTED"));
  8869. hr = E_UNEXPECTED;
  8870. }
  8871. }
  8872. else
  8873. {
  8874. //
  8875. // if we have an address line, send a message to the corresponding line
  8876. //
  8877. hr = LineReceiveMSPData(
  8878. pAddressLine->t3Line.hLine,
  8879. hCall,
  8880. pEvent->MSP_TSP_DATA.pBuffer,
  8881. pEvent->MSP_TSP_DATA.dwBufferSize
  8882. );
  8883. //
  8884. // no longer need our address line, release it. the line will be closed
  8885. // if needed
  8886. //
  8887. pCall->ReleaseAddressLine(pAddressLine);
  8888. pAddressLine = NULL;
  8889. }
  8890. //
  8891. // if we have a call, release it
  8892. //
  8893. if (NULL != pCall)
  8894. {
  8895. pCall->Release();
  8896. pCall = NULL;
  8897. }
  8898. LOG((TL_INFO, "HandleSendTSPData - finish hr = %lx", hr));
  8899. return hr;
  8900. }
  8901. //
  8902. // handle dev specific message
  8903. //
  8904. void HandleLineDevSpecificMessage( PASYNCEVENTMSG pParams )
  8905. {
  8906. LOG((TL_INFO, "HandleLineDevSpecificMessage - enter"));
  8907. //
  8908. // note:
  8909. //
  8910. // unfortunately, the message that we receive does not give us any
  8911. // indication as to whether hDevice contains a call handle or am address
  8912. // handle.
  8913. //
  8914. // to determine the kind of handle, we have to search both tables. if we
  8915. // find the corresponding address object, this is a line handle, if we find
  8916. // a corresponding call, this is a call handle. this brute-force search is
  8917. // fairly expensive.
  8918. //
  8919. // one possible optimization would be to track the number of calls and
  8920. // addresses and search the smaller table first. however, this would
  8921. // require tracking overhead (even in the cases where the optimization is
  8922. // not needed), and for this to work well, we would also need to estimate
  8923. // the likelyhood of each type of message. which makes this kind of
  8924. // optimization even more expensive.
  8925. //
  8926. // so we will simply check both tables to determine whether we have a call
  8927. // or an address.
  8928. //
  8929. CCall *pCall = NULL;
  8930. CAddress *pAddress = NULL;
  8931. //
  8932. // find the corresponding address
  8933. //
  8934. if ( !FindAddressObject( (HLINE)(pParams->hDevice), &pAddress ) )
  8935. {
  8936. LOG((TL_WARN,
  8937. "HandleLineDevSpecificMessage - FindAddressObject failed to find matching address. searching for call"));
  8938. pAddress = NULL;
  8939. //
  8940. // no address, try to find matching call
  8941. //
  8942. if ( !FindCallObject( (HCALL)(pParams->hDevice), &pCall) )
  8943. {
  8944. LOG((TL_ERROR,
  8945. "HandleLineDevSpecificMessage - FindAddressObject failed to find matching call. "));
  8946. return;
  8947. }
  8948. }
  8949. //
  8950. // if we got a call, get the corresponding address object
  8951. //
  8952. if (NULL != pCall)
  8953. {
  8954. ITAddress *pITAddress = NULL;
  8955. HRESULT hr = pCall->get_Address(&pITAddress);
  8956. if (FAILED(hr))
  8957. {
  8958. LOG((TL_ERROR,
  8959. "HandleLineDevSpecificMessage - call does not have an address. hr = %lx", hr));
  8960. pCall->Release();
  8961. pCall = NULL;
  8962. return;
  8963. }
  8964. try
  8965. {
  8966. pAddress = dynamic_cast<CAddress*>(pITAddress);
  8967. }
  8968. catch(...)
  8969. {
  8970. LOG((TL_ERROR,
  8971. "HandleLineDevSpecificMessage - exception using address. address pointer bad"));
  8972. }
  8973. //
  8974. // if the address is bad, return
  8975. //
  8976. if (NULL == pAddress)
  8977. {
  8978. LOG((TL_ERROR,
  8979. "HandleLineDevSpecificMessage - no address"));
  8980. pCall->Release();
  8981. pCall = NULL;
  8982. //
  8983. // yes, queryinterface returned us an addreffed pITAddress... but
  8984. // since it does not seem valid anyway, do not bother releasing.
  8985. //
  8986. _ASSERTE(FALSE);
  8987. return;
  8988. }
  8989. } // call is not null
  8990. //
  8991. // by this time we must have an address and maybe a call. we actually
  8992. // ensured this in the logic above. this assert is to make this condition
  8993. // explicit.
  8994. //
  8995. _ASSERTE( NULL != pAddress );
  8996. //
  8997. // fire event
  8998. //
  8999. CAddressDevSpecificEvent::FireEvent(
  9000. pAddress,
  9001. pCall,
  9002. pParams->Param1,
  9003. pParams->Param2,
  9004. pParams->Param3
  9005. );
  9006. //
  9007. // undo FindXObject's addreffs
  9008. //
  9009. if (NULL != pAddress)
  9010. {
  9011. pAddress->Release();
  9012. pAddress = NULL;
  9013. }
  9014. if (NULL != pCall)
  9015. {
  9016. pCall->Release();
  9017. pCall = NULL;
  9018. }
  9019. LOG((TL_INFO, "HandleLineDevSpecificMessage - exit. "));
  9020. }
  9021. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9022. //
  9023. // HandleMSPAddressEvent
  9024. //
  9025. // fires an addressevent to the application based on
  9026. // an event from the MSP
  9027. //
  9028. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9029. HRESULT
  9030. CAddress::HandleMSPAddressEvent( MSP_EVENT_INFO * pEvent )
  9031. {
  9032. switch ( pEvent->MSP_ADDRESS_EVENT_INFO.Type )
  9033. {
  9034. case ADDRESS_TERMINAL_AVAILABLE:
  9035. CAddressEvent::FireEvent(
  9036. this,
  9037. AE_NEWTERMINAL,
  9038. pEvent->MSP_ADDRESS_EVENT_INFO.pTerminal
  9039. );
  9040. break;
  9041. case ADDRESS_TERMINAL_UNAVAILABLE:
  9042. CAddressEvent::FireEvent(
  9043. this,
  9044. AE_REMOVETERMINAL,
  9045. pEvent->MSP_ADDRESS_EVENT_INFO.pTerminal
  9046. );
  9047. break;
  9048. default:
  9049. LOG((TL_ERROR, "HandleMSPAddressEvent - bad event"));
  9050. break;
  9051. }
  9052. return S_OK;
  9053. }
  9054. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9055. //
  9056. // HandleMSPCallEvent
  9057. //
  9058. // fires a callmediaevent to the application based on an
  9059. // event from the msp
  9060. //
  9061. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9062. HRESULT
  9063. CAddress::HandleMSPCallEvent( MSP_EVENT_INFO * pEvent )
  9064. {
  9065. CCall * pCall;
  9066. ITCallInfo * pCallInfo;
  9067. CALL_MEDIA_EVENT Event;
  9068. CALL_MEDIA_EVENT_CAUSE Cause;
  9069. ITTerminal * pTerminal = NULL;
  9070. ITStream * pStream = NULL;
  9071. HRESULT hrEvent = 0;
  9072. HRESULT hr = S_OK;
  9073. gpHandleHashTable->Lock();
  9074. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  9075. if ( SUCCEEDED(hr) )
  9076. {
  9077. LOG((TL_INFO, "HandleMSPCallEvent - Matched handle %X to Call object %p", pEvent->hCall, pCall ));
  9078. pCall->AddRef();
  9079. gpHandleHashTable->Unlock();
  9080. hr = pCall->QueryInterface(
  9081. IID_ITCallInfo,
  9082. (void**) &pCallInfo
  9083. );
  9084. }
  9085. else // ( !SUCCEEDED(hr) )
  9086. {
  9087. LOG((TL_ERROR, "HandleMSPCallEvent - Couldn't match handle %X to Call object ", pEvent->hCall));
  9088. gpHandleHashTable->Unlock();
  9089. return hr;
  9090. }
  9091. //
  9092. // set up the info for the event
  9093. // pStream applies to all of the currently-defined events
  9094. //
  9095. pStream = pEvent->MSP_CALL_EVENT_INFO.pStream;
  9096. //
  9097. // cause is the same, although the MSPI and API use different enumerated types.
  9098. // Note: this will have to expand to a switch if the order of enums ever gets
  9099. // out of sync!
  9100. //
  9101. Cause = (CALL_MEDIA_EVENT_CAUSE) pEvent->MSP_CALL_EVENT_INFO.Cause;
  9102. //
  9103. // Rest depend on the type...
  9104. //
  9105. switch ( pEvent->MSP_CALL_EVENT_INFO.Type )
  9106. {
  9107. case CALL_NEW_STREAM:
  9108. Event = CME_NEW_STREAM;
  9109. break;
  9110. case CALL_STREAM_FAIL:
  9111. Event = CME_STREAM_FAIL;
  9112. hrEvent = pEvent->MSP_CALL_EVENT_INFO.hrError;
  9113. break;
  9114. case CALL_TERMINAL_FAIL:
  9115. Event = CME_TERMINAL_FAIL;
  9116. pTerminal = pEvent->MSP_CALL_EVENT_INFO.pTerminal;
  9117. hrEvent = pEvent->MSP_CALL_EVENT_INFO.hrError;
  9118. break;
  9119. case CALL_STREAM_NOT_USED:
  9120. Event = CME_STREAM_NOT_USED;
  9121. break;
  9122. case CALL_STREAM_ACTIVE:
  9123. Event = CME_STREAM_ACTIVE;
  9124. break;
  9125. case CALL_STREAM_INACTIVE:
  9126. Event = CME_STREAM_INACTIVE;
  9127. break;
  9128. default:
  9129. LOG((TL_ERROR, "HandleMSPCallEvent - bad event"));
  9130. return E_INVALIDARG;
  9131. }
  9132. //
  9133. // fire the event
  9134. //
  9135. CCallMediaEvent::FireEvent(
  9136. pCallInfo,
  9137. Event,
  9138. Cause,
  9139. dynamic_cast<CTAPI *>(m_pTAPI),
  9140. pTerminal,
  9141. pStream,
  9142. hrEvent
  9143. );
  9144. //
  9145. // addref'd above
  9146. //
  9147. pCallInfo->Release();
  9148. pCall->Release();
  9149. return S_OK;
  9150. }
  9151. HRESULT
  9152. CAddress::HandleMSPTTSTerminalEvent( MSP_EVENT_INFO * pEvent )
  9153. {
  9154. if (NULL == pEvent)
  9155. {
  9156. LOG((TL_ERROR, "HandleMSPTTSTerminalEvent - pEvent is NULL"));
  9157. return E_POINTER;
  9158. }
  9159. ITAddress *pAddress = dynamic_cast<ITAddress *>(this);
  9160. if (pAddress == NULL)
  9161. {
  9162. LOG((TL_ERROR, "HandleMSPTTSTerminalEvent - can't cast the address %p to ITAddress", this));
  9163. return E_UNEXPECTED;
  9164. }
  9165. CCall * pCall = NULL;
  9166. ITCallInfo * pCallInfo = NULL;
  9167. gpHandleHashTable->Lock();
  9168. HRESULT hr = E_FAIL;
  9169. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  9170. if ( SUCCEEDED(hr) )
  9171. {
  9172. LOG((TL_INFO, "HandleMSPTTSTerminalEvent - Matched handle %X to Call object %p", pEvent->hCall, pCall ));
  9173. pCall->AddRef();
  9174. gpHandleHashTable->Unlock();
  9175. hr = pCall->QueryInterface(
  9176. IID_ITCallInfo,
  9177. (void**) &pCallInfo
  9178. );
  9179. }
  9180. else // ( !SUCCEEDED(hr) )
  9181. {
  9182. LOG((TL_ERROR, "HandleMSPTTSTerminalEvent - Couldn't match handle %X to Call object ", pEvent->hCall));
  9183. gpHandleHashTable->Unlock();
  9184. return hr;
  9185. }
  9186. //
  9187. // get tapi object and fire the event
  9188. //
  9189. hr = CTTSTerminalEvent::FireEvent(GetTapi(),
  9190. pCallInfo,
  9191. pEvent->MSP_TTS_TERMINAL_EVENT_INFO.pTTSTerminal,
  9192. pEvent->MSP_TTS_TERMINAL_EVENT_INFO.hrErrorCode);
  9193. if (FAILED(hr))
  9194. {
  9195. LOG((TL_ERROR, "HandleMSPTTSTerminalEvent - CFileTerminalEvent::FireEvent failed. hr = %lx", hr));
  9196. }
  9197. //
  9198. // we addref'd these above, so release now
  9199. //
  9200. pCallInfo->Release();
  9201. pCall->Release();
  9202. return hr;
  9203. }
  9204. HRESULT
  9205. CAddress::HandleMSPASRTerminalEvent( MSP_EVENT_INFO * pEvent )
  9206. {
  9207. if (NULL == pEvent)
  9208. {
  9209. LOG((TL_ERROR, "HandleMSPASRTerminalEvent - pEvent is NULL"));
  9210. return E_POINTER;
  9211. }
  9212. ITAddress *pAddress = dynamic_cast<ITAddress *>(this);
  9213. if (pAddress == NULL)
  9214. {
  9215. LOG((TL_ERROR, "HandleMSPASRTerminalEvent - can't cast the address %p to ITAddress", this));
  9216. return E_UNEXPECTED;
  9217. }
  9218. CCall * pCall = NULL;
  9219. ITCallInfo * pCallInfo = NULL;
  9220. gpHandleHashTable->Lock();
  9221. HRESULT hr = E_FAIL;
  9222. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  9223. if ( SUCCEEDED(hr) )
  9224. {
  9225. LOG((TL_INFO, "HandleMSPASRTerminalEvent - Matched handle %X to Call object %p", pEvent->hCall, pCall ));
  9226. pCall->AddRef();
  9227. gpHandleHashTable->Unlock();
  9228. hr = pCall->QueryInterface(
  9229. IID_ITCallInfo,
  9230. (void**) &pCallInfo
  9231. );
  9232. }
  9233. else // ( !SUCCEEDED(hr) )
  9234. {
  9235. LOG((TL_ERROR, "HandleMSPASRTerminalEvent - Couldn't match handle %X to Call object ", pEvent->hCall));
  9236. gpHandleHashTable->Unlock();
  9237. return hr;
  9238. }
  9239. //
  9240. // get tapi object and fire the event
  9241. //
  9242. hr = CASRTerminalEvent::FireEvent(GetTapi(),
  9243. pCallInfo,
  9244. pEvent->MSP_ASR_TERMINAL_EVENT_INFO.pASRTerminal,
  9245. pEvent->MSP_ASR_TERMINAL_EVENT_INFO.hrErrorCode);
  9246. if (FAILED(hr))
  9247. {
  9248. LOG((TL_ERROR, "HandleMSPASRTerminalEvent - CFileTerminalEvent::FireEvent failed. hr = %lx", hr));
  9249. }
  9250. //
  9251. // we addref'd these above, so release now
  9252. //
  9253. pCallInfo->Release();
  9254. pCall->Release();
  9255. return hr;
  9256. }
  9257. HRESULT
  9258. CAddress::HandleMSPToneTerminalEvent( MSP_EVENT_INFO * pEvent )
  9259. {
  9260. if (NULL == pEvent)
  9261. {
  9262. LOG((TL_ERROR, "HandleMSPToneTerminalEvent - pEvent is NULL"));
  9263. return E_POINTER;
  9264. }
  9265. ITAddress *pAddress = dynamic_cast<ITAddress *>(this);
  9266. if (pAddress == NULL)
  9267. {
  9268. LOG((TL_ERROR, "HandleMSPToneTerminalEvent - can't cast the address %p to ITAddress", this));
  9269. return E_UNEXPECTED;
  9270. }
  9271. CCall * pCall = NULL;
  9272. ITCallInfo * pCallInfo = NULL;
  9273. gpHandleHashTable->Lock();
  9274. HRESULT hr = E_FAIL;
  9275. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  9276. if ( SUCCEEDED(hr) )
  9277. {
  9278. LOG((TL_INFO, "HandleMSPToneTerminalEvent - Matched handle %X to Call object %p", pEvent->hCall, pCall ));
  9279. pCall->AddRef();
  9280. gpHandleHashTable->Unlock();
  9281. hr = pCall->QueryInterface(
  9282. IID_ITCallInfo,
  9283. (void**) &pCallInfo
  9284. );
  9285. }
  9286. else // ( !SUCCEEDED(hr) )
  9287. {
  9288. LOG((TL_ERROR, "HandleMSPToneTerminalEvent - Couldn't match handle %X to Call object ", pEvent->hCall));
  9289. gpHandleHashTable->Unlock();
  9290. return hr;
  9291. }
  9292. //
  9293. // get tapi object and fire the event
  9294. //
  9295. hr = CToneTerminalEvent::FireEvent(GetTapi(),
  9296. pCallInfo,
  9297. pEvent->MSP_TONE_TERMINAL_EVENT_INFO.pToneTerminal,
  9298. pEvent->MSP_TONE_TERMINAL_EVENT_INFO.hrErrorCode);
  9299. if (FAILED(hr))
  9300. {
  9301. LOG((TL_ERROR, "HandleMSPToneTerminalEvent - CFileTerminalEvent::FireEvent failed. hr = %lx", hr));
  9302. }
  9303. //
  9304. // we addref'd these above, so release now
  9305. //
  9306. pCallInfo->Release();
  9307. pCall->Release();
  9308. return hr;
  9309. }
  9310. HRESULT
  9311. CAddress::HandleMSPFileTerminalEvent( MSP_EVENT_INFO * pEvent )
  9312. {
  9313. if (NULL == pEvent)
  9314. {
  9315. LOG((TL_ERROR, "HandleMSPFileTerminalEvent - pEvent is NULL"));
  9316. return E_POINTER;
  9317. }
  9318. ITAddress *pAddress = dynamic_cast<ITAddress *>(this);
  9319. if (pAddress == NULL)
  9320. {
  9321. LOG((TL_ERROR, "HandleMSPFileTerminalEvent - can't cast the address %p to ITAddress", this));
  9322. return E_UNEXPECTED;
  9323. }
  9324. CCall * pCall = NULL;
  9325. ITCallInfo * pCallInfo = NULL;
  9326. gpHandleHashTable->Lock();
  9327. HRESULT hr = E_FAIL;
  9328. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  9329. if ( SUCCEEDED(hr) )
  9330. {
  9331. LOG((TL_INFO, "HandleMSPFileTerminalEvent - Matched handle %X to Call object %p", pEvent->hCall, pCall ));
  9332. pCall->AddRef();
  9333. gpHandleHashTable->Unlock();
  9334. hr = pCall->QueryInterface(
  9335. IID_ITCallInfo,
  9336. (void**) &pCallInfo
  9337. );
  9338. }
  9339. else // ( !SUCCEEDED(hr) )
  9340. {
  9341. LOG((TL_ERROR, "HandleMSPFileTerminalEvent - Couldn't match handle %X to Call object ", pEvent->hCall));
  9342. gpHandleHashTable->Unlock();
  9343. return hr;
  9344. }
  9345. //
  9346. // get tapi object and fire the event
  9347. //
  9348. hr = CFileTerminalEvent::FireEvent(this,
  9349. GetTapi(),
  9350. pCallInfo,
  9351. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.TerminalMediaState,
  9352. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.ftecEventCause,
  9353. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pParentFileTerminal,
  9354. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pFileTrack,
  9355. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.hrErrorCode);
  9356. if (FAILED(hr))
  9357. {
  9358. LOG((TL_ERROR, "HandleMSPFileTerminalEvent - CFileTerminalEvent::FireEvent failed. hr = %lx", hr));
  9359. }
  9360. //
  9361. // we addref'd these above, so release now
  9362. //
  9363. pCallInfo->Release();
  9364. pCall->Release();
  9365. return hr;
  9366. }
  9367. HRESULT
  9368. CAddress::HandleMSPPrivateEvent( MSP_EVENT_INFO * pEvent )
  9369. {
  9370. ITAddress *pAddress = dynamic_cast<ITAddress *>(this);
  9371. if (pAddress == NULL)
  9372. {
  9373. LOG((TL_ERROR, "HandleMSPPrivateEvent - can't cast the address %p to ITAddress", this));
  9374. return E_UNEXPECTED;
  9375. }
  9376. CCall * pCall = NULL;
  9377. ITCallInfo * pCallInfo = NULL;
  9378. HRESULT hr;
  9379. gpHandleHashTable->Lock();
  9380. hr = gpHandleHashTable->Find( (ULONG_PTR)pEvent->hCall, (ULONG_PTR *)&pCall);
  9381. if ( SUCCEEDED(hr) )
  9382. {
  9383. LOG((TL_INFO, "HandleMSPPrivateEvent - Matched handle %X to Call object %p", pEvent->hCall, pCall ));
  9384. pCall->AddRef();
  9385. gpHandleHashTable->Unlock();
  9386. hr = pCall->QueryInterface(
  9387. IID_ITCallInfo,
  9388. (void**) &pCallInfo
  9389. );
  9390. }
  9391. else // ( !SUCCEEDED(hr) )
  9392. {
  9393. LOG((TL_ERROR, "HandleMSPPrivateEvent - Couldn't match handle %X to Call object ", pEvent->hCall));
  9394. gpHandleHashTable->Unlock();
  9395. return hr;
  9396. }
  9397. CPrivateEvent::FireEvent(
  9398. GetTapi(),
  9399. pCallInfo,
  9400. pAddress,
  9401. NULL,
  9402. pEvent->MSP_PRIVATE_EVENT_INFO.pEvent,
  9403. pEvent->MSP_PRIVATE_EVENT_INFO.lEventCode
  9404. );
  9405. //
  9406. // addref'd above
  9407. //
  9408. pCallInfo->Release();
  9409. pCall->Release();
  9410. return hr;
  9411. }
  9412. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9413. //
  9414. // ReleaseEvent
  9415. //
  9416. // releases any reference counts in the event from
  9417. // the msp.
  9418. //
  9419. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9420. HRESULT
  9421. CAddress::ReleaseEvent( MSP_EVENT_INFO * pEvent )
  9422. {
  9423. LOG((TL_TRACE, "ReleaseEvent - enter"));
  9424. switch ( pEvent->Event )
  9425. {
  9426. case ME_ADDRESS_EVENT:
  9427. if (NULL != pEvent->MSP_ADDRESS_EVENT_INFO.pTerminal)
  9428. {
  9429. (pEvent->MSP_ADDRESS_EVENT_INFO.pTerminal)->Release();
  9430. }
  9431. break;
  9432. case ME_CALL_EVENT:
  9433. if (NULL != pEvent->MSP_CALL_EVENT_INFO.pTerminal)
  9434. {
  9435. (pEvent->MSP_CALL_EVENT_INFO.pTerminal)->Release();
  9436. }
  9437. if (NULL != pEvent->MSP_CALL_EVENT_INFO.pStream)
  9438. {
  9439. (pEvent->MSP_CALL_EVENT_INFO.pStream)->Release();
  9440. }
  9441. break;
  9442. case ME_TSP_DATA:
  9443. break;
  9444. case ME_PRIVATE_EVENT:
  9445. if ( NULL != pEvent->MSP_PRIVATE_EVENT_INFO.pEvent )
  9446. {
  9447. (pEvent->MSP_PRIVATE_EVENT_INFO.pEvent)->Release();
  9448. }
  9449. break;
  9450. case ME_FILE_TERMINAL_EVENT:
  9451. if( NULL != pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pParentFileTerminal)
  9452. {
  9453. (pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pParentFileTerminal)->Release();
  9454. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pParentFileTerminal = NULL;
  9455. }
  9456. if( NULL != pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pFileTrack )
  9457. {
  9458. (pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pFileTrack)->Release();
  9459. pEvent->MSP_FILE_TERMINAL_EVENT_INFO.pFileTrack = NULL;
  9460. }
  9461. break;
  9462. case ME_ASR_TERMINAL_EVENT:
  9463. if( NULL != pEvent->MSP_ASR_TERMINAL_EVENT_INFO.pASRTerminal)
  9464. {
  9465. (pEvent->MSP_ASR_TERMINAL_EVENT_INFO.pASRTerminal)->Release();
  9466. }
  9467. break;
  9468. case ME_TTS_TERMINAL_EVENT:
  9469. if( NULL != pEvent->MSP_TTS_TERMINAL_EVENT_INFO.pTTSTerminal)
  9470. {
  9471. (pEvent->MSP_TTS_TERMINAL_EVENT_INFO.pTTSTerminal)->Release();
  9472. }
  9473. break;
  9474. case ME_TONE_TERMINAL_EVENT:
  9475. if( NULL != pEvent->MSP_TONE_TERMINAL_EVENT_INFO.pToneTerminal)
  9476. {
  9477. (pEvent->MSP_TONE_TERMINAL_EVENT_INFO.pToneTerminal)->Release();
  9478. }
  9479. break;
  9480. default:
  9481. break;
  9482. }
  9483. LOG((TL_TRACE, "ReleaseEvent - finished"));
  9484. return S_OK;
  9485. }
  9486. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9487. // HRESULT
  9488. // CAddress::MSPEvent()
  9489. //
  9490. // gets an event buffer from the MSP
  9491. // and calls the relevant event handler
  9492. //
  9493. // this is _only_ called from the asynceventsthread. this is
  9494. // necessary for synchronization of events.
  9495. //
  9496. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9497. HRESULT
  9498. CAddress::MSPEvent()
  9499. {
  9500. DWORD dwSize;
  9501. MSP_EVENT_INFO * pEvent = NULL;
  9502. HRESULT hr;
  9503. //
  9504. // Allocate an MSP event buffer -- best guess as to an appropriate
  9505. // size. We need to free it before returning.
  9506. //
  9507. dwSize = sizeof (MSP_EVENT_INFO) + 500;
  9508. pEvent = (MSP_EVENT_INFO *)ClientAlloc( dwSize );
  9509. if ( NULL == pEvent )
  9510. {
  9511. LOG((TL_ERROR, "Alloc failed in MSP event"));
  9512. return E_OUTOFMEMORY;
  9513. }
  9514. pEvent->dwSize = dwSize;
  9515. //
  9516. // Get pointer to msp address object. We need to release it before returning.
  9517. // This must be done while the address object is locked.
  9518. //
  9519. Lock();
  9520. ITMSPAddress * pMSPAddress = GetMSPAddress();
  9521. Unlock();
  9522. while (TRUE)
  9523. {
  9524. //
  9525. // Get an event from the event queue. Abort and clean up if
  9526. // allocation fails.
  9527. //
  9528. do
  9529. {
  9530. hr = pMSPAddress->GetEvent(
  9531. &dwSize,
  9532. (LPBYTE)pEvent
  9533. );
  9534. if ( hr == TAPI_E_NOTENOUGHMEMORY)
  9535. {
  9536. ClientFree( pEvent );
  9537. pEvent = (MSP_EVENT_INFO *)ClientAlloc( dwSize );
  9538. if ( NULL == pEvent )
  9539. {
  9540. LOG((TL_ERROR, "Alloc failed in MSP event"));
  9541. pMSPAddress->Release();
  9542. return E_OUTOFMEMORY;
  9543. }
  9544. pEvent->dwSize = dwSize;
  9545. }
  9546. } while ( hr == TAPI_E_NOTENOUGHMEMORY );
  9547. //
  9548. // If there is nothing left in the MSP event queue, then stop the
  9549. // outer while loop.
  9550. //
  9551. if ( !SUCCEEDED(hr) )
  9552. {
  9553. break;
  9554. }
  9555. //
  9556. // Call the relevant handler, and do not hold the address lock during
  9557. // the call.
  9558. //
  9559. switch ( pEvent->Event )
  9560. {
  9561. case ME_ADDRESS_EVENT:
  9562. HandleMSPAddressEvent( pEvent );
  9563. break;
  9564. case ME_CALL_EVENT:
  9565. HandleMSPCallEvent( pEvent );
  9566. break;
  9567. case ME_TSP_DATA:
  9568. HandleSendTSPData( pEvent );
  9569. break;
  9570. case ME_PRIVATE_EVENT:
  9571. HandleMSPPrivateEvent( pEvent );
  9572. break;
  9573. case ME_FILE_TERMINAL_EVENT:
  9574. HandleMSPFileTerminalEvent( pEvent );
  9575. break;
  9576. case ME_ASR_TERMINAL_EVENT:
  9577. HandleMSPASRTerminalEvent( pEvent );
  9578. break;
  9579. case ME_TTS_TERMINAL_EVENT:
  9580. HandleMSPTTSTerminalEvent( pEvent );
  9581. break;
  9582. case ME_TONE_TERMINAL_EVENT:
  9583. HandleMSPToneTerminalEvent( pEvent );
  9584. break;
  9585. default:
  9586. break;
  9587. }
  9588. //
  9589. // release any refcounts in the
  9590. // event
  9591. //
  9592. ReleaseEvent( pEvent );
  9593. }
  9594. //
  9595. // We get here when there is nothing more to retrieve from the
  9596. // MSP event queue.
  9597. //
  9598. pMSPAddress->Release();
  9599. ClientFree( pEvent );
  9600. return hr;
  9601. }
  9602. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9603. //
  9604. //
  9605. //
  9606. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9607. ITMSPAddress * CAddress::GetMSPAddress()
  9608. {
  9609. ITMSPAddress * pMSPAddress = NULL;
  9610. if ( NULL != m_pMSPAggAddress )
  9611. {
  9612. m_pMSPAggAddress->QueryInterface(IID_ITMSPAddress, (void**)&pMSPAddress);
  9613. }
  9614. return pMSPAddress;
  9615. }
  9616. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9617. //
  9618. //
  9619. //
  9620. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9621. STDMETHODIMP
  9622. CAddress::GetID(
  9623. BSTR pDeviceClass,
  9624. DWORD * pdwSize,
  9625. BYTE ** ppDeviceID
  9626. )
  9627. {
  9628. HRESULT hr;
  9629. PtrList::iterator iter;
  9630. LPVARSTRING pVarString = NULL;
  9631. if ( IsBadStringPtrW( pDeviceClass, -1 ) )
  9632. {
  9633. LOG((TL_ERROR, "GetID - bad string"));
  9634. return E_POINTER;
  9635. }
  9636. if ( TAPIIsBadWritePtr( pdwSize, sizeof(DWORD)))
  9637. {
  9638. LOG((TL_ERROR, "GetID - bad size"));
  9639. return E_POINTER;
  9640. }
  9641. if ( TAPIIsBadWritePtr( ppDeviceID, sizeof(BYTE *) ) )
  9642. {
  9643. LOG((TL_ERROR, "GetID - bad pointer"));
  9644. return E_POINTER;
  9645. }
  9646. Lock();
  9647. if ( m_AddressLinesPtrList.size() > 0 )
  9648. {
  9649. iter = m_AddressLinesPtrList.begin();
  9650. }
  9651. else
  9652. {
  9653. Unlock();
  9654. return E_FAIL;
  9655. }
  9656. hr = LineGetID(
  9657. ((AddressLineStruct *)*iter)->t3Line.hLine,
  9658. m_dwAddressID,
  9659. NULL,
  9660. LINECALLSELECT_ADDRESS,
  9661. &pVarString,
  9662. pDeviceClass
  9663. );
  9664. Unlock();
  9665. if ( SUCCEEDED(hr) )
  9666. {
  9667. *ppDeviceID = (BYTE *)CoTaskMemAlloc( pVarString->dwUsedSize );
  9668. if ( *ppDeviceID != NULL )
  9669. {
  9670. CopyMemory(
  9671. *ppDeviceID,
  9672. ((LPBYTE)pVarString)+pVarString->dwStringOffset,
  9673. pVarString->dwStringSize
  9674. );
  9675. *pdwSize = pVarString->dwStringSize;
  9676. }
  9677. else
  9678. {
  9679. hr = E_OUTOFMEMORY;
  9680. }
  9681. }
  9682. if ( NULL != pVarString )
  9683. {
  9684. ClientFree( pVarString );
  9685. }
  9686. return hr;
  9687. }
  9688. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9689. // Class : CAddress
  9690. // Interface : ITLegacyAddressMediaControl
  9691. // Method : GetDevConfig
  9692. //
  9693. // Get Device Config
  9694. //
  9695. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9696. STDMETHODIMP
  9697. CAddress::GetDevConfig(
  9698. BSTR pDeviceClass,
  9699. DWORD * pdwSize,
  9700. BYTE ** ppDeviceConfig
  9701. )
  9702. {
  9703. HRESULT hr;
  9704. LPVARSTRING pVarString = NULL;
  9705. LOG((TL_TRACE, "GetDevConfig - enter"));
  9706. if ( IsBadStringPtrW( pDeviceClass, -1 ) )
  9707. {
  9708. LOG((TL_ERROR, "GetDevConfig - bad DeviceClass string"));
  9709. return E_POINTER;
  9710. }
  9711. if ( TAPIIsBadWritePtr( pdwSize, sizeof(DWORD)))
  9712. {
  9713. LOG((TL_ERROR, "GetDevConfig - bad size"));
  9714. return E_POINTER;
  9715. }
  9716. if ( TAPIIsBadWritePtr( ppDeviceConfig, sizeof(BYTE*) ) )
  9717. {
  9718. LOG((TL_ERROR, "GetDevConfig - bad buffer pointer"));
  9719. return E_POINTER;
  9720. }
  9721. Lock();
  9722. hr = LineGetDevConfig(m_dwDeviceID,
  9723. &pVarString,
  9724. pDeviceClass
  9725. );
  9726. Unlock();
  9727. if ( SUCCEEDED(hr) )
  9728. {
  9729. *ppDeviceConfig = (BYTE *)CoTaskMemAlloc( pVarString->dwUsedSize );
  9730. if(*ppDeviceConfig != NULL)
  9731. {
  9732. CopyMemory(
  9733. *ppDeviceConfig,
  9734. ((LPBYTE)pVarString)+pVarString->dwStringOffset,
  9735. pVarString->dwStringSize
  9736. );
  9737. *pdwSize = pVarString->dwStringSize;
  9738. }
  9739. else
  9740. {
  9741. hr = E_OUTOFMEMORY;
  9742. }
  9743. }
  9744. if ( NULL != pVarString )
  9745. {
  9746. ClientFree( pVarString );
  9747. }
  9748. LOG((TL_TRACE, hr, "GetDevConfig - exit" ));
  9749. return hr;
  9750. }
  9751. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9752. // Class : CAddress
  9753. // Interface : ITLegacyAddressMediaControl
  9754. // Method : SetDevConfig
  9755. //
  9756. // Set Device Config
  9757. //
  9758. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9759. STDMETHODIMP
  9760. CAddress::SetDevConfig(
  9761. BSTR pDeviceClass,
  9762. DWORD dwSize,
  9763. BYTE * pDeviceConfig
  9764. )
  9765. {
  9766. HRESULT hr = S_OK;
  9767. LOG((TL_TRACE, "SetDevConfig - enter"));
  9768. if ( IsBadStringPtrW( pDeviceClass, -1) )
  9769. {
  9770. LOG((TL_ERROR, "SetDevConfig - bad string pointer"));
  9771. return E_POINTER;
  9772. }
  9773. if (dwSize == 0)
  9774. {
  9775. LOG((TL_ERROR, "SetDevConfig - dwSize = 0"));
  9776. return E_INVALIDARG;
  9777. }
  9778. if (IsBadReadPtr( pDeviceConfig, dwSize) )
  9779. {
  9780. LOG((TL_ERROR, "SetDevConfig - bad pointer"));
  9781. return E_POINTER;
  9782. }
  9783. Lock();
  9784. hr = lineSetDevConfigW(m_dwDeviceID,
  9785. pDeviceConfig,
  9786. dwSize,
  9787. pDeviceClass
  9788. );
  9789. Unlock();
  9790. LOG((TL_TRACE, hr, "SetDevConfig - exit"));
  9791. return hr;
  9792. }
  9793. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9794. // Class : CAddress
  9795. // Interface : ITLegacyAddressMediaControl2
  9796. // Method : ConfigDialog
  9797. //
  9798. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9799. STDMETHODIMP
  9800. CAddress::ConfigDialog(
  9801. HWND hwndOwner,
  9802. BSTR pDeviceClass
  9803. )
  9804. {
  9805. HRESULT hr = S_OK;
  9806. LOG((TL_TRACE, "ConfigDialog - enter"));
  9807. if ( (pDeviceClass != NULL) && IsBadStringPtrW( pDeviceClass, -1) )
  9808. {
  9809. LOG((TL_ERROR, "ConfigDialog - bad string pointer"));
  9810. return E_POINTER;
  9811. }
  9812. Lock();
  9813. hr = LineConfigDialogW(
  9814. m_dwDeviceID,
  9815. hwndOwner,
  9816. pDeviceClass
  9817. );
  9818. Unlock();
  9819. LOG((TL_TRACE, hr, "ConfigDialog - exit"));
  9820. return hr;
  9821. }
  9822. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9823. // Class : CAddress
  9824. // Interface : ITLegacyAddressMediaControl2
  9825. // Method : ConfigDialogEdit
  9826. //
  9827. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9828. STDMETHODIMP
  9829. CAddress::ConfigDialogEdit(
  9830. HWND hwndOwner,
  9831. BSTR pDeviceClass,
  9832. DWORD dwSizeIn,
  9833. BYTE * pDeviceConfigIn,
  9834. DWORD * pdwSizeOut,
  9835. BYTE ** ppDeviceConfigOut
  9836. )
  9837. {
  9838. HRESULT hr = S_OK;
  9839. LPVARSTRING pVarString = NULL;
  9840. LOG((TL_TRACE, "ConfigDialogEdit - enter"));
  9841. if ( (pDeviceClass != NULL) && IsBadStringPtrW( pDeviceClass, -1) )
  9842. {
  9843. LOG((TL_ERROR, "ConfigDialogEdit - bad string pointer"));
  9844. return E_POINTER;
  9845. }
  9846. if (dwSizeIn == 0)
  9847. {
  9848. LOG((TL_ERROR, "ConfigDialogEdit - dwSize = 0"));
  9849. return E_INVALIDARG;
  9850. }
  9851. if (IsBadReadPtr( pDeviceConfigIn, dwSizeIn) )
  9852. {
  9853. LOG((TL_ERROR, "ConfigDialogEdit - bad pointer"));
  9854. return E_POINTER;
  9855. }
  9856. if ( TAPIIsBadWritePtr( pdwSizeOut, sizeof(DWORD)))
  9857. {
  9858. LOG((TL_ERROR, "ConfigDialogEdit - bad size"));
  9859. return E_POINTER;
  9860. }
  9861. if ( TAPIIsBadWritePtr( ppDeviceConfigOut, sizeof(BYTE*) ) )
  9862. {
  9863. LOG((TL_ERROR, "ConfigDialogEdit - bad buffer pointer"));
  9864. return E_POINTER;
  9865. }
  9866. Lock();
  9867. hr = LineConfigDialogEditW(
  9868. m_dwDeviceID,
  9869. hwndOwner,
  9870. pDeviceClass,
  9871. pDeviceConfigIn,
  9872. dwSizeIn,
  9873. &pVarString
  9874. );
  9875. Unlock();
  9876. if ( SUCCEEDED(hr) )
  9877. {
  9878. *ppDeviceConfigOut = (BYTE *)CoTaskMemAlloc( pVarString->dwUsedSize );
  9879. if(*ppDeviceConfigOut != NULL)
  9880. {
  9881. CopyMemory(
  9882. *ppDeviceConfigOut,
  9883. ((LPBYTE)pVarString)+pVarString->dwStringOffset,
  9884. pVarString->dwStringSize
  9885. );
  9886. *pdwSizeOut = pVarString->dwStringSize;
  9887. }
  9888. else
  9889. {
  9890. hr = E_OUTOFMEMORY;
  9891. }
  9892. }
  9893. if ( NULL != pVarString )
  9894. {
  9895. ClientFree( pVarString );
  9896. }
  9897. LOG((TL_TRACE, hr, "ConfigDialogEdit - exit"));
  9898. return hr;
  9899. }
  9900. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9901. //
  9902. //
  9903. //
  9904. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9905. HRESULT HandleLineCloseMessage( PASYNCEVENTMSG pParams )
  9906. {
  9907. CAddress * pAddress;
  9908. AddressLineStruct * pAddressLine;
  9909. CTAPI * pTapi;
  9910. ITAddress * pITAddress;
  9911. LOG((TL_TRACE, "HandleLineCloseMessage - enter"));
  9912. if ( !FindAddressObject(
  9913. (HLINE)(pParams->hDevice),
  9914. &pAddress
  9915. ) )
  9916. {
  9917. LOG((TL_TRACE, "HandleLineCloseMessage - FindAddressObject failed. exiting... "));
  9918. return S_OK;
  9919. }
  9920. pTapi = pAddress->GetTapi();
  9921. pAddress->QueryInterface(
  9922. IID_ITAddress,
  9923. (void **)&pITAddress
  9924. );
  9925. //
  9926. // get the lock so that the address line does not go away meanwhile
  9927. //
  9928. pAddress->Lock();
  9929. //
  9930. // covert the 32bit address line handle (contained in pParams->OpenContext)
  9931. // into a pointer value
  9932. //
  9933. pAddressLine = (AddressLineStruct *)GetHandleTableEntry(pParams->OpenContext);
  9934. //
  9935. // is this a good line anyway?
  9936. //
  9937. BOOL bValidLine = pAddress->IsValidAddressLine(pAddressLine);
  9938. long lCallBackInstance = 0;
  9939. //
  9940. // if seems to be a good line, attempt to get callback instance from it.
  9941. //
  9942. if (bValidLine)
  9943. {
  9944. try
  9945. {
  9946. lCallBackInstance = pAddressLine->lCallbackInstance;
  9947. }
  9948. catch(...)
  9949. {
  9950. LOG((TL_ERROR,
  9951. "HandleLineCloseMessage - exception getting callback instance from line struc"));
  9952. _ASSERTE(FALSE);
  9953. bValidLine = FALSE;
  9954. }
  9955. }
  9956. pAddress->Unlock();
  9957. //
  9958. // if good and known line, attempt to fire an event
  9959. //
  9960. if ( bValidLine && pTapi && pTapi->FindRegistration( (PVOID)pAddressLine ) )
  9961. {
  9962. LOG((TL_TRACE, "HandleLineCloseMessage - found registration, firing event"));
  9963. CTapiObjectEvent::FireEvent(
  9964. pTapi,
  9965. TE_ADDRESSCLOSE,
  9966. pITAddress,
  9967. lCallBackInstance,
  9968. NULL
  9969. );
  9970. }
  9971. else
  9972. {
  9973. LOG((TL_TRACE,
  9974. "HandleLineCloseMessage AddressLine %p not found. calling maybeclosealine",
  9975. pAddressLine ));
  9976. pAddress->MaybeCloseALine(&pAddressLine);
  9977. }
  9978. pITAddress->Release();
  9979. //FindAddressObject addrefs the address objct
  9980. pAddress->Release();
  9981. LOG((TL_TRACE, "HandleLineCloseMessage - exit"));
  9982. return S_OK;
  9983. }
  9984. /////////////////////////////////////////////////////////////////////////////
  9985. // IDispatch implementation
  9986. //
  9987. typedef IDispatchImpl<ITAddress2Vtbl<CAddress>, &IID_ITAddress2, &LIBID_TAPI3Lib> AddressType;
  9988. typedef IDispatchImpl<ITAddressCapabilitiesVtbl<CAddress>, &IID_ITAddressCapabilities, &LIBID_TAPI3Lib> AddressCapabilitiesType;
  9989. typedef IDispatchImpl<ITMediaSupportVtbl<CAddress>, &IID_ITMediaSupport, &LIBID_TAPI3Lib> MediaSupportType;
  9990. typedef IDispatchImpl<ITAddressTranslationVtbl<CAddress>, &IID_ITAddressTranslation, &LIBID_TAPI3Lib> AddressTranslationType;
  9991. typedef IDispatchImpl<ITLegacyAddressMediaControl2Vtbl<CAddress>, &IID_ITLegacyAddressMediaControl2, &LIBID_TAPI3Lib> LegacyAddressMediaControlType;
  9992. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9993. //
  9994. // CAddress::GetIDsOfNames
  9995. //
  9996. // Overide if IDispatch method
  9997. //
  9998. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  9999. STDMETHODIMP CAddress::GetIDsOfNames(REFIID riid,
  10000. LPOLESTR* rgszNames,
  10001. UINT cNames,
  10002. LCID lcid,
  10003. DISPID* rgdispid
  10004. )
  10005. {
  10006. HRESULT hr = DISP_E_UNKNOWNNAME;
  10007. // See if the requsted method belongs to the default interface
  10008. hr = AddressType::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  10009. if (SUCCEEDED(hr))
  10010. {
  10011. LOG((TL_INFO, "GetIDsOfNames - found %S on ITAddress", *rgszNames));
  10012. rgdispid[0] |= IDISPADDRESS;
  10013. return hr;
  10014. }
  10015. // If not, then try the Address Capabilities interface
  10016. hr = AddressCapabilitiesType::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  10017. if (SUCCEEDED(hr))
  10018. {
  10019. LOG((TL_INFO, "GetIDsOfNames - found %S on ITAddressCapabilities", *rgszNames));
  10020. rgdispid[0] |= IDISPADDRESSCAPABILITIES;
  10021. return hr;
  10022. }
  10023. // If not, then try the Media Support interface
  10024. hr = MediaSupportType::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  10025. if (SUCCEEDED(hr))
  10026. {
  10027. LOG((TL_INFO, "GetIDsOfNames - found %S on ITMediaSupport", *rgszNames));
  10028. rgdispid[0] |= IDISPMEDIASUPPORT;
  10029. return hr;
  10030. }
  10031. // If not, then try the Address Translation interface
  10032. hr = AddressTranslationType::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  10033. if (SUCCEEDED(hr))
  10034. {
  10035. LOG((TL_INFO, "GetIDsOfNames - found %S on ITAddressTranslation", *rgszNames));
  10036. rgdispid[0] |= IDISPADDRESSTRANSLATION;
  10037. return hr;
  10038. }
  10039. // If not, then try the Legacy Address Media Control interface
  10040. hr = LegacyAddressMediaControlType::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  10041. if (SUCCEEDED(hr))
  10042. {
  10043. LOG((TL_INFO, "GetIDsOfNames - found %S on ITLegacyAddressMediaControl", *rgszNames));
  10044. rgdispid[0] |= IDISPLEGACYADDRESSMEDIACONTROL;
  10045. return hr;
  10046. }
  10047. // If not, then try the aggregated MSP Address object
  10048. if (m_pMSPAggAddress != NULL)
  10049. {
  10050. IDispatch *pIDispatchMSPAggAddress;
  10051. m_pMSPAggAddress->QueryInterface(IID_IDispatch, (void**)&pIDispatchMSPAggAddress);
  10052. hr = pIDispatchMSPAggAddress->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  10053. if (SUCCEEDED(hr))
  10054. {
  10055. pIDispatchMSPAggAddress->Release();
  10056. LOG((TL_INFO, "GetIDsOfNames - found %S on our aggregated MSP Address", *rgszNames));
  10057. rgdispid[0] |= IDISPAGGREGATEDMSPADDRESSOBJ;
  10058. return hr;
  10059. }
  10060. pIDispatchMSPAggAddress->Release();
  10061. }
  10062. LOG((TL_INFO, "GetIDsOfNames - Didn't find %S on our iterfaces", *rgszNames));
  10063. return hr;
  10064. }
  10065. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  10066. //
  10067. // CAddress::Invoke
  10068. //
  10069. // Overide if IDispatch method
  10070. //
  10071. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  10072. STDMETHODIMP CAddress::Invoke(DISPID dispidMember,
  10073. REFIID riid,
  10074. LCID lcid,
  10075. WORD wFlags,
  10076. DISPPARAMS* pdispparams,
  10077. VARIANT* pvarResult,
  10078. EXCEPINFO* pexcepinfo,
  10079. UINT* puArgErr
  10080. )
  10081. {
  10082. HRESULT hr = DISP_E_MEMBERNOTFOUND;
  10083. DWORD dwInterface = (dispidMember & INTERFACEMASK);
  10084. LOG((TL_TRACE, "Invoke - dispidMember %X", dispidMember));
  10085. // Call invoke for the required interface
  10086. switch (dwInterface)
  10087. {
  10088. case IDISPADDRESS:
  10089. {
  10090. hr = AddressType::Invoke(dispidMember,
  10091. riid,
  10092. lcid,
  10093. wFlags,
  10094. pdispparams,
  10095. pvarResult,
  10096. pexcepinfo,
  10097. puArgErr
  10098. );
  10099. break;
  10100. }
  10101. case IDISPADDRESSCAPABILITIES:
  10102. {
  10103. hr = AddressCapabilitiesType::Invoke(dispidMember,
  10104. riid,
  10105. lcid,
  10106. wFlags,
  10107. pdispparams,
  10108. pvarResult,
  10109. pexcepinfo,
  10110. puArgErr
  10111. );
  10112. break;
  10113. }
  10114. case IDISPMEDIASUPPORT:
  10115. {
  10116. hr = MediaSupportType::Invoke(dispidMember,
  10117. riid,
  10118. lcid,
  10119. wFlags,
  10120. pdispparams,
  10121. pvarResult,
  10122. pexcepinfo,
  10123. puArgErr
  10124. );
  10125. break;
  10126. }
  10127. case IDISPADDRESSTRANSLATION:
  10128. {
  10129. hr = AddressTranslationType::Invoke(dispidMember,
  10130. riid,
  10131. lcid,
  10132. wFlags,
  10133. pdispparams,
  10134. pvarResult,
  10135. pexcepinfo,
  10136. puArgErr
  10137. );
  10138. break;
  10139. }
  10140. case IDISPLEGACYADDRESSMEDIACONTROL:
  10141. {
  10142. hr = LegacyAddressMediaControlType::Invoke(dispidMember,
  10143. riid,
  10144. lcid,
  10145. wFlags,
  10146. pdispparams,
  10147. pvarResult,
  10148. pexcepinfo,
  10149. puArgErr
  10150. );
  10151. break;
  10152. }
  10153. case IDISPAGGREGATEDMSPADDRESSOBJ:
  10154. {
  10155. IDispatch *pIDispatchMSPAggAddress = NULL;
  10156. if (m_pMSPAggAddress != NULL)
  10157. {
  10158. m_pMSPAggAddress->QueryInterface(IID_IDispatch, (void**)&pIDispatchMSPAggAddress);
  10159. hr = pIDispatchMSPAggAddress->Invoke(dispidMember,
  10160. riid,
  10161. lcid,
  10162. wFlags,
  10163. pdispparams,
  10164. pvarResult,
  10165. pexcepinfo,
  10166. puArgErr
  10167. );
  10168. pIDispatchMSPAggAddress->Release();
  10169. }
  10170. break;
  10171. }
  10172. } // end switch (dwInterface)
  10173. LOG((TL_TRACE, hr, "Invoke - exit" ));
  10174. return hr;
  10175. }
  10176. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  10177. //
  10178. // CAddress::IsValidAddressLine
  10179. //
  10180. // returns TRUE if the address line passed in is in the address line list
  10181. //
  10182. // This method is not thread safe -- all calls must be protected, unless
  10183. // bAddRef argument is TRUE
  10184. //
  10185. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
  10186. BOOL CAddress::IsValidAddressLine(AddressLineStruct *pAddressLine, BOOL bAddref)
  10187. {
  10188. if (IsBadReadPtr(pAddressLine, sizeof(AddressLineStruct) ) )
  10189. {
  10190. LOG((TL_WARN,
  10191. "IsValidAddressLine - unreadeable memory at [%p]",
  10192. pAddressLine));
  10193. return FALSE;
  10194. }
  10195. if (bAddref)
  10196. {
  10197. Lock();
  10198. }
  10199. PtrList::iterator it = m_AddressLinesPtrList.begin();
  10200. PtrList::iterator end = m_AddressLinesPtrList.end();
  10201. // iterate through address line list until we find the line
  10202. for ( ; it != end; it++ )
  10203. {
  10204. if (pAddressLine == (AddressLineStruct *)(*it))
  10205. {
  10206. if (bAddref)
  10207. {
  10208. //
  10209. // addref the line and release the lock
  10210. //
  10211. try
  10212. {
  10213. pAddressLine->AddRef();
  10214. }
  10215. catch(...)
  10216. {
  10217. //
  10218. // this is a bug. debug.
  10219. //
  10220. LOG((TL_INFO, "IsValidAddressLine -- exception while addreffing the line"));
  10221. _ASSERTE(FALSE);
  10222. Unlock();
  10223. return FALSE;
  10224. }
  10225. Unlock();
  10226. }
  10227. LOG((TL_INFO, "IsValidAddressLine returning TRUE"));
  10228. return TRUE;
  10229. }
  10230. }
  10231. if (bAddref)
  10232. {
  10233. Unlock();
  10234. }
  10235. LOG((TL_INFO, "IsValidAddressLine returning FALSE"));
  10236. return FALSE;
  10237. }
  10238. /////////////////////////////////////////////////////////////
  10239. //
  10240. // implementing method from CObjectSafeImpl
  10241. //
  10242. // check the aggregated objects to see if they support the interface requested.
  10243. // if they do, return the non-delegating IUnknown of the object that supports
  10244. // the interface.
  10245. //
  10246. HRESULT CAddress::QIOnAggregates(REFIID riid, IUnknown **ppNonDelegatingUnknown)
  10247. {
  10248. //
  10249. // argument check
  10250. //
  10251. if ( TAPIIsBadWritePtr(ppNonDelegatingUnknown, sizeof(IUnknown*)) )
  10252. {
  10253. return E_POINTER;
  10254. }
  10255. //
  10256. // if we fail, at least return consistent values
  10257. //
  10258. *ppNonDelegatingUnknown = NULL;
  10259. //
  10260. // see if m_pMSPAggAddress or private support the interface riid
  10261. //
  10262. HRESULT hr = E_FAIL;
  10263. Lock();
  10264. if (m_pMSPAggAddress)
  10265. {
  10266. //
  10267. // does m_pMSPAggAddress expose this interface?
  10268. //
  10269. IUnknown *pUnk = NULL;
  10270. hr = m_pMSPAggAddress->QueryInterface(riid, (void**)&pUnk);
  10271. if (SUCCEEDED(hr))
  10272. {
  10273. pUnk->Release();
  10274. pUnk = NULL;
  10275. //
  10276. // return the mspcall's non-delegating unknown
  10277. //
  10278. *ppNonDelegatingUnknown = m_pMSPAggAddress;
  10279. (*ppNonDelegatingUnknown)->AddRef();
  10280. }
  10281. }
  10282. if ( FAILED(hr) && m_pPrivate )
  10283. {
  10284. //
  10285. // bad luck with m_pMSPAggAddress? still have a chance with private
  10286. //
  10287. IUnknown *pUnk = NULL;
  10288. hr = m_pPrivate->QueryInterface(riid, (void**)&pUnk);
  10289. if (SUCCEEDED(hr))
  10290. {
  10291. pUnk->Release();
  10292. pUnk = NULL;
  10293. *ppNonDelegatingUnknown = m_pPrivate;
  10294. (*ppNonDelegatingUnknown)->AddRef();
  10295. }
  10296. }
  10297. Unlock();
  10298. return hr;
  10299. }
  10300. //
  10301. // Event filtering methods
  10302. //
  10303. /*++
  10304. SetEventFilterMask
  10305. Is called by TAPI object to set the event filter mask to each address
  10306. The caller method is CTAPI::SetEventFilterToAddresses()
  10307. dwEventFilterMask is the TAPI event filter mask
  10308. --*/
  10309. HRESULT CAddress::SetEventFilterMask(
  10310. DWORD dwEventFilterMask
  10311. )
  10312. {
  10313. LOG((TL_TRACE, "SetEventFilterMask - enter. dwEventFilterMask[%lx]", dwEventFilterMask ));
  10314. //
  10315. // Set the event mask for all TAPI events
  10316. //
  10317. // TE_ADDRESS
  10318. SetSubEventFlag(
  10319. TE_ADDRESS,
  10320. CEventMasks::EM_ALLSUBEVENTS,
  10321. (dwEventFilterMask & TE_ADDRESS) ? TRUE : FALSE);
  10322. // TE_CALLHUB
  10323. SetSubEventFlag(
  10324. TE_CALLHUB,
  10325. CEventMasks::EM_ALLSUBEVENTS,
  10326. (dwEventFilterMask & TE_CALLHUB) ? TRUE : FALSE);
  10327. // TE_CALLINFOCHANGE
  10328. SetSubEventFlag(
  10329. TE_CALLINFOCHANGE,
  10330. CEventMasks::EM_ALLSUBEVENTS,
  10331. (dwEventFilterMask & TE_CALLINFOCHANGE) ? TRUE : FALSE);
  10332. // TE_CALLMEDIA
  10333. SetSubEventFlag(
  10334. TE_CALLMEDIA,
  10335. CEventMasks::EM_ALLSUBEVENTS,
  10336. (dwEventFilterMask & TE_CALLMEDIA) ? TRUE : FALSE);
  10337. // TE_CALLNOTIFICATION
  10338. SetSubEventFlag(
  10339. TE_CALLNOTIFICATION,
  10340. CEventMasks::EM_ALLSUBEVENTS,
  10341. (dwEventFilterMask & TE_CALLNOTIFICATION) ? TRUE : FALSE);
  10342. // TE_CALLSTATE
  10343. SetSubEventFlag(
  10344. TE_CALLSTATE,
  10345. CEventMasks::EM_ALLSUBEVENTS,
  10346. (dwEventFilterMask & TE_CALLSTATE) ? TRUE : FALSE);
  10347. // TE_FILETERMINAL
  10348. SetSubEventFlag(
  10349. TE_FILETERMINAL,
  10350. CEventMasks::EM_ALLSUBEVENTS,
  10351. (dwEventFilterMask & TE_FILETERMINAL) ? TRUE : FALSE);
  10352. // TE_PRIVATE
  10353. SetSubEventFlag(
  10354. TE_PRIVATE,
  10355. CEventMasks::EM_ALLSUBEVENTS,
  10356. (dwEventFilterMask & TE_PRIVATE) ? TRUE : FALSE);
  10357. // TE_QOSEVENT
  10358. SetSubEventFlag(
  10359. TE_QOSEVENT,
  10360. CEventMasks::EM_ALLSUBEVENTS,
  10361. (dwEventFilterMask & TE_QOSEVENT) ? TRUE : FALSE);
  10362. // TE_ADDRESSDEVSPECIFIC
  10363. SetSubEventFlag(
  10364. TE_ADDRESSDEVSPECIFIC,
  10365. CEventMasks::EM_ALLSUBEVENTS,
  10366. (dwEventFilterMask & TE_ADDRESSDEVSPECIFIC) ? TRUE : FALSE);
  10367. // TE_PHONEDEVSPECIFIC
  10368. SetSubEventFlag(
  10369. TE_PHONEDEVSPECIFIC,
  10370. CEventMasks::EM_ALLSUBEVENTS,
  10371. (dwEventFilterMask & TE_PHONEDEVSPECIFIC) ? TRUE : FALSE);
  10372. LOG((TL_TRACE, "SetEventFilterMask exit S_OK"));
  10373. return S_OK;
  10374. }
  10375. /*++
  10376. SetSubEventFlag
  10377. Sets in m_EventFilterMasks array the bitflag for an subevent
  10378. Is called by CAddress::SetEventFilterMask
  10379. --*/
  10380. HRESULT CAddress::SetSubEventFlag(
  10381. TAPI_EVENT TapiEvent,
  10382. DWORD dwSubEvent,
  10383. BOOL bEnable
  10384. )
  10385. {
  10386. LOG((TL_TRACE,
  10387. "SetSubEventFlag - enter. event [%lx] subevent[%lx] enable?[%d]",
  10388. TapiEvent, dwSubEvent, bEnable ));
  10389. HRESULT hr = S_OK;
  10390. //
  10391. // Set the mask for the event
  10392. //
  10393. hr = m_EventMasks.SetSubEventFlag(
  10394. TapiEvent,
  10395. dwSubEvent,
  10396. bEnable);
  10397. if( SUCCEEDED(hr) )
  10398. {
  10399. hr = SetSubEventFlagToCalls(
  10400. TapiEvent,
  10401. dwSubEvent,
  10402. bEnable
  10403. );
  10404. }
  10405. LOG((TL_TRACE, "SetSubEventFlag exit 0x%08x", hr));
  10406. return hr;
  10407. }
  10408. /*++
  10409. GetSubEventFlag
  10410. It is calle by get_EventFilter() method
  10411. --*/
  10412. HRESULT CAddress::GetSubEventFlag(
  10413. TAPI_EVENT TapiEvent,
  10414. DWORD dwSubEvent,
  10415. BOOL* pEnable
  10416. )
  10417. {
  10418. LOG((TL_TRACE, "GetSubEventFlag enter" ));
  10419. HRESULT hr = E_FAIL;
  10420. //
  10421. // Get the subevent falg
  10422. //
  10423. hr = m_EventMasks.GetSubEventFlag(
  10424. TapiEvent,
  10425. dwSubEvent,
  10426. pEnable
  10427. );
  10428. LOG((TL_TRACE, "GetSubEventFlag exit 0x%08x", hr));
  10429. return hr;
  10430. }
  10431. /*++
  10432. SetSubEventFlagToCalls
  10433. Sets the flags to all calls
  10434. Is called by SetSubEventFlag() method
  10435. --*/
  10436. HRESULT CAddress::SetSubEventFlagToCalls(
  10437. TAPI_EVENT TapiEvent,
  10438. DWORD dwSubEvent,
  10439. BOOL bEnable
  10440. )
  10441. {
  10442. LOG((TL_TRACE, "SetSubEventFlagToCalls enter" ));
  10443. HRESULT hr = S_OK;
  10444. //
  10445. // Apply the sub event filter mask to all the calls on this address
  10446. //
  10447. for (int nCall = 0; nCall < m_CallArray.GetSize() ; nCall++ )
  10448. {
  10449. CCall * pCall = NULL;
  10450. pCall = dynamic_cast<CCall *>(m_CallArray[nCall]);
  10451. if ( NULL != pCall )
  10452. {
  10453. hr = pCall->SetSubEventFlag(
  10454. TapiEvent,
  10455. dwSubEvent,
  10456. bEnable
  10457. );
  10458. if( FAILED(hr) )
  10459. {
  10460. break;
  10461. }
  10462. }
  10463. }
  10464. LOG((TL_TRACE, "SetSubEventFlagToCalls exit 0x%08x", hr));
  10465. return hr;
  10466. }
  10467. /*++
  10468. GetSubEventsMask
  10469. Is called by SetSubEventFlag to get the sub events mask for
  10470. a specific TAPI_EVENT
  10471. Assumed is called into a Lock statement
  10472. --*/
  10473. DWORD CAddress::GetSubEventsMask(
  10474. IN TAPI_EVENT TapiEvent
  10475. )
  10476. {
  10477. LOG((TL_TRACE, "GetSubEventsMask - enter"));
  10478. DWORD dwSubEventFlag = m_EventMasks.GetSubEventMask( TapiEvent );
  10479. LOG((TL_TRACE, "GetSubEventsMask - exit %ld", dwSubEventFlag));
  10480. return dwSubEventFlag;
  10481. }
  10482. /*++
  10483. GetEventMasks
  10484. It is called by CCall::Initialize()
  10485. --*/
  10486. HRESULT CAddress::GetEventMasks(
  10487. OUT CEventMasks* pEventMasks
  10488. )
  10489. {
  10490. LOG((TL_TRACE, "GetEventMasks - enter"));
  10491. m_EventMasks.CopyEventMasks( pEventMasks );
  10492. LOG((TL_TRACE, "GetEventMasks - exit S_OK"));
  10493. return S_OK;
  10494. }
  10495. ////////////////////////////////////////////
  10496. //
  10497. // RegisterNotificationCookie
  10498. //
  10499. // adds the specified cookie to the list of cookies on this address
  10500. //
  10501. HRESULT CAddress::RegisterNotificationCookie(long lCookie)
  10502. {
  10503. HRESULT hr = S_OK;
  10504. LOG((TL_INFO,
  10505. "RegisterNotificationCookie - adding cookie %lx to m_NotificationCookies list",
  10506. lCookie ));
  10507. Lock();
  10508. try
  10509. {
  10510. m_NotificationCookies.push_back(lCookie);
  10511. }
  10512. catch(...)
  10513. {
  10514. LOG((TL_ERROR,
  10515. "RegisterNotificationCookie - failed to add a cookie to m_NotificationCookies list - alloc failure" ));
  10516. hr = E_OUTOFMEMORY;
  10517. }
  10518. Unlock();
  10519. return hr;
  10520. }
  10521. ////////////////////////////////////////////
  10522. //
  10523. // RemoveNotificationCookie
  10524. //
  10525. // removes the specified cookie from this address's cookies
  10526. //
  10527. HRESULT CAddress::RemoveNotificationCookie(long lCookie)
  10528. {
  10529. HRESULT hr = S_OK;
  10530. LOG((TL_INFO,
  10531. "RemoveNotificationCookie - removing cookie %lx from m_NotificationCookies list",
  10532. lCookie ));
  10533. Lock();
  10534. m_NotificationCookies.remove(lCookie);
  10535. Unlock();
  10536. return hr;
  10537. }
  10538. ////////////////////////////////////////////
  10539. //
  10540. // UnregisterAllCookies
  10541. //
  10542. // removes all cookies from this address's cookie list
  10543. //
  10544. // for each valid cookie, call RemoveCallNotification
  10545. //
  10546. void CAddress::UnregisterAllCookies()
  10547. {
  10548. LOG((TL_TRACE, "UnregisterAllCookies entering. this[%p]", this));
  10549. Lock();
  10550. LongList::iterator it = m_NotificationCookies.begin();
  10551. LongList::iterator end = m_NotificationCookies.end();
  10552. //
  10553. // if there are any cookies, remove the corresponding registeritems
  10554. // from the handlehashtable
  10555. //
  10556. // also, unregister call notification for these cookies, to make sure
  10557. // everything is cleaned up (and in particular that lineCloseMSPInstance
  10558. // gets called if needed so the tsp gets notified that the msp is going
  10559. // away
  10560. //
  10561. for ( ; it != end; it++ )
  10562. {
  10563. long lCookie = (long)(*it);
  10564. LOG((TL_INFO, "UnregisterAllCookies removing handle %lx", lCookie));
  10565. //
  10566. // get register item, so we can unregister call notifications with it.
  10567. //
  10568. REGISTERITEM *pRegisterItem = (REGISTERITEM*) GetHandleTableEntry(lCookie);
  10569. //
  10570. // remove the entry from the handle table
  10571. //
  10572. RemoveHandleFromHashTable(lCookie);
  10573. //
  10574. // if we did not get a good registeritem that corresponds to this cookie,
  10575. // go on to the next cookie
  10576. //
  10577. if ( (NULL == pRegisterItem) ||
  10578. IsBadReadPtr(pRegisterItem, sizeof(REGISTERITEM)) )
  10579. {
  10580. LOG((TL_INFO,
  10581. "UnregisterAllCookies - no corresponfing registeritem for cookie 0x%lx",
  10582. lCookie));
  10583. continue;
  10584. }
  10585. //
  10586. // if the register item is not RA_ADDRESS, ignore it and go on to
  10587. // the next cookie.
  10588. //
  10589. if (RA_ADDRESS != pRegisterItem->dwType)
  10590. {
  10591. LOG((TL_INFO,
  10592. "UnregisterAllCookies - cookie 0x%lx is of type 0x%lx, not RA_ADDRESS",
  10593. lCookie,
  10594. pRegisterItem->dwType));
  10595. continue;
  10596. }
  10597. //
  10598. // remove call notification for this cookie, since the app did not
  10599. // do this. best effort -- ignore the error code.
  10600. //
  10601. LOG((TL_INFO,
  10602. "UnregisterAllCookies - removing call notification for cookie 0x%lx",
  10603. lCookie));
  10604. RemoveCallNotification(pRegisterItem->pRegister);
  10605. }
  10606. //
  10607. // clear cookie list
  10608. //
  10609. m_NotificationCookies.clear();
  10610. Unlock();
  10611. LOG((TL_TRACE, "UnregisterAllCookies exiting"));
  10612. }
  10613. ///////////////////////////////////////////////////////////////////////////////
  10614. //
  10615. // CAddress::AddressOnTapiShutdown
  10616. //
  10617. // this function is called by the owner tapi object when it is going away.
  10618. //
  10619. // we then propagate tapi shutdown notification to each call, so the calls
  10620. // can do their clean up
  10621. //
  10622. void CAddress::AddressOnTapiShutdown()
  10623. {
  10624. LOG((TL_TRACE, "AddressOnTapiShutdown - enter"));
  10625. //
  10626. // protect access to m_CallArray
  10627. //
  10628. Lock();
  10629. //
  10630. // tell each call to clean up
  10631. //
  10632. int nCalls = m_CallArray.GetSize();
  10633. for (int i = 0; i < nCalls; i++)
  10634. {
  10635. ITCallInfo *pCallInfo = m_CallArray[i];
  10636. try
  10637. {
  10638. //
  10639. // get a pointer to the call object
  10640. //
  10641. CCall *pCallObject = dynamic_cast<CCall *>(pCallInfo);
  10642. if (NULL == pCallObject)
  10643. {
  10644. //
  10645. // the pointer is not pointing to a call object. this is odd
  10646. // and is worth debugging
  10647. //
  10648. LOG((TL_ERROR,
  10649. "AddressOnTapiShutdown - invalid call pointer[%p] in the call array",
  10650. pCallInfo));
  10651. _ASSERTE(FALSE);
  10652. }
  10653. else
  10654. {
  10655. //
  10656. // tell the call that it's time to go
  10657. //
  10658. pCallObject->CallOnTapiShutdown();
  10659. }
  10660. }
  10661. catch(...)
  10662. {
  10663. //
  10664. // not only is the pointer not pointing to a call object, but it is
  10665. // also pointing to memory that is not readable. how did this happen?
  10666. //
  10667. LOG((TL_ERROR,
  10668. "AddressOnTapiShutdown - unreadable call pointer[%p] in the call array",
  10669. pCallInfo));
  10670. _ASSERTE(FALSE);
  10671. }
  10672. }
  10673. //
  10674. // set the flag so no new calls are created following this
  10675. //
  10676. m_bTapiSignaledShutdown = TRUE;
  10677. //
  10678. // unregister the msp wait event in the thread pool. we don't want to get
  10679. // any callbacks after tapi has shut down
  10680. //
  10681. if ( NULL != m_hWaitEvent )
  10682. {
  10683. LOG((TL_TRACE, "AddressOnTapiShutdown - unregistering the MSPEventCallback callback"));
  10684. UnregisterWaitEx( m_hWaitEvent, INVALID_HANDLE_VALUE);
  10685. m_hWaitEvent = NULL;
  10686. }
  10687. Unlock();
  10688. LOG((TL_TRACE, "AddressOnTapiShutdown - finish"));
  10689. }