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.

680 lines
17 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. acdgroup.cpp
  5. Abstract:
  6. Implementation of the ACD Group object for TAPI 3.0.
  7. CACDGroup class
  8. Author:
  9. noela - 11/04/97
  10. Notes:
  11. optional-notes
  12. Revision History:
  13. --*/
  14. #include "stdafx.h"
  15. HRESULT
  16. WaitForReply(
  17. DWORD
  18. );
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CACDGroup
  21. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  22. // Class : CACDGroup
  23. // Method : Initialize
  24. //
  25. //
  26. //
  27. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  28. STDMETHODIMP CACDGroup::Initialize
  29. (
  30. PWSTR pszGroupName,
  31. GUID GroupHandle,
  32. CAgentHandler * pHandler
  33. )
  34. {
  35. HRESULT hr = S_OK;
  36. LOG((TL_TRACE, "Initialize - enter" ));
  37. m_GroupHandle = GroupHandle;
  38. m_pHandler = pHandler;
  39. m_bActive = TRUE;
  40. // copy the destination address
  41. if (pszGroupName != NULL)
  42. {
  43. m_szName = (PWSTR) ClientAlloc((lstrlenW(pszGroupName) + 1) * sizeof (WCHAR));
  44. if (m_szName != NULL)
  45. {
  46. lstrcpyW(m_szName,pszGroupName);
  47. }
  48. else
  49. {
  50. LOG((TL_ERROR, "Initialize - Alloc m_szName failed" ));
  51. hr = E_OUTOFMEMORY;
  52. }
  53. }
  54. else
  55. {
  56. LOG((TL_INFO, "Initialize - name is NULL" ));
  57. m_szName = NULL;
  58. }
  59. if ( SUCCEEDED(hr) )
  60. {
  61. // Fire event here
  62. CACDGroupEvent::FireEvent(this, ACDGE_NEW_GROUP);
  63. }
  64. LOG((TL_TRACE, hr, "Initialize - exit" ));
  65. return hr;
  66. }
  67. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  68. // Class : CACDGroup
  69. // Method : FinalRelease
  70. //
  71. //
  72. //
  73. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  74. void CACDGroup::FinalRelease()
  75. {
  76. LOG(( TL_TRACE, "FinalRelease ACD Group - %S", m_szName ));
  77. if ( m_szName != NULL )
  78. {
  79. ClientFree(m_szName);
  80. }
  81. m_QueueArray.Shutdown();
  82. LOG((TL_TRACE, "FinalRelease ACD Group - exit"));
  83. }
  84. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  85. // Class : CACDGroup
  86. // Method : SetActive
  87. //
  88. //
  89. //
  90. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  91. void CACDGroup::SetActive()
  92. {
  93. if ( !m_bActive )
  94. {
  95. LOG((TL_INFO, "SetActive - Set Group To Active"));
  96. m_bActive = TRUE;
  97. // Fire event here
  98. CACDGroupEvent::FireEvent(this, ACDGE_NEW_GROUP);
  99. }
  100. else
  101. {
  102. LOG((TL_INFO, "SetActive - Already Active"));
  103. }
  104. }
  105. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  106. // Class : CACDGroup
  107. // Method : SetInactive
  108. //
  109. //
  110. //
  111. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  112. void CACDGroup::SetInactive()
  113. {
  114. if ( m_bActive )
  115. {
  116. LOG((TL_INFO, "SetInactive - Set Group To Inactive"));
  117. m_bActive = FALSE;
  118. // Fire event here
  119. CACDGroupEvent::FireEvent(this, ACDGE_GROUP_REMOVED);
  120. }
  121. else
  122. {
  123. LOG((TL_INFO, "SetInactive - Already Inactive"));
  124. }
  125. }
  126. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. // Class : CACDGroup
  128. // Method : active
  129. // Overloaded function !
  130. //
  131. //
  132. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  133. inline BOOL CACDGroup::active(HRESULT * hr)
  134. {
  135. if(m_bActive)
  136. {
  137. *hr = S_OK;
  138. }
  139. else
  140. {
  141. LOG((TL_ERROR, "Group inactive" ));
  142. *hr = E_UNEXPECTED;
  143. }
  144. return m_bActive;
  145. }
  146. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  147. // Class : CACDGroup
  148. // Method : UpdateAgentHandlerList
  149. //
  150. //
  151. //
  152. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  153. HRESULT CACDGroup::UpdateQueueArray()
  154. {
  155. HRESULT hr = S_OK;
  156. DWORD dwNumberOfEntries;
  157. LPLINEQUEUELIST pQueueList = NULL;
  158. LPLINEQUEUEENTRY pQueueEntry = NULL;
  159. PWSTR pszQueueName;
  160. DWORD dwQueueID, dwCount;
  161. int iCount;
  162. BOOL foundIt;
  163. CQueue * thisQueue = NULL;
  164. LOG((TL_TRACE, "UpdateQueueArray - enter"));
  165. // Call LineGetQueulist to get list of Queues
  166. hr = lineGetQueueList(
  167. m_pHandler->getHLine(),
  168. &m_GroupHandle,
  169. &pQueueList
  170. );
  171. if( SUCCEEDED(hr) )
  172. {
  173. dwNumberOfEntries = pQueueList->dwNumEntries;
  174. // Find position of 1st LINEQUEUEENTRY structure in the LINEQUEUELIST
  175. pQueueEntry = (LPLINEQUEUEENTRY) ((BYTE*)(pQueueList) + pQueueList->dwListOffset);
  176. // Run though the received list
  177. for (dwCount = 0; dwCount < dwNumberOfEntries; dwCount++)
  178. {
  179. int iCount;
  180. pszQueueName= (PWSTR)( (PBYTE)pQueueList + pQueueEntry->dwNameOffset);
  181. dwQueueID = pQueueEntry->dwQueueID;
  182. LOG((TL_INFO, "UpdateQueueArray - Queue Name : %S", pszQueueName));
  183. LOG((TL_INFO, "UpdateQueueArray - Queue Handle : %d", dwQueueID));
  184. // Run through the list of Queues & see if we already have this one in the list
  185. // by comparing IDs
  186. foundIt = FALSE;
  187. Lock();
  188. for (iCount = 0; iCount < m_QueueArray.GetSize(); iCount++)
  189. {
  190. thisQueue = dynamic_cast<CComObject<CQueue>*>(m_QueueArray[iCount]);
  191. if (thisQueue != NULL)
  192. {
  193. if ( dwQueueID == thisQueue->getID() )
  194. {
  195. foundIt = TRUE;
  196. break;
  197. }
  198. }
  199. }
  200. Unlock();
  201. if (foundIt == FALSE)
  202. {
  203. // Didn't match so lets add this Queue
  204. LOG((TL_INFO, "UpdateQueueArray - create new Queue"));
  205. CComObject<CQueue> * pQueue;
  206. hr = CComObject<CQueue>::CreateInstance( &pQueue );
  207. if( SUCCEEDED(hr) )
  208. {
  209. ITQueue * pITQueue;
  210. hr = pQueue->QueryInterface(IID_ITQueue, (void **)&pITQueue);
  211. if ( SUCCEEDED(hr) )
  212. {
  213. // initialize the Queue
  214. hr = pQueue->Initialize(dwQueueID, pszQueueName, m_pHandler);
  215. if( SUCCEEDED(hr) )
  216. {
  217. // add to list of CQueues
  218. Lock();
  219. m_QueueArray.Add(pITQueue);
  220. Unlock();
  221. pITQueue->Release();
  222. LOG((TL_INFO, "UpdateQueueArray - Added Queue to list"));
  223. }
  224. else
  225. {
  226. LOG((TL_ERROR, "UpdateQueueArray - Initialize Queue failed" ));
  227. delete pQueue;
  228. }
  229. }
  230. else
  231. {
  232. LOG((TL_ERROR, "UpdateQueueArray - QueryInterface ITQueue failed" ));
  233. delete pQueue;
  234. }
  235. }
  236. else
  237. {
  238. LOG((TL_ERROR, "UpdateQueueArray - Create Queue failed" ));
  239. }
  240. }
  241. else // foundIt == TRUE
  242. {
  243. LOG((TL_INFO, "UpdateQueueArray - Queue Object exists for this entry" ));
  244. }
  245. // next entry in list
  246. pQueueEntry ++;
  247. } //for(dwCount = 0......)
  248. }
  249. else // LineGetQueuelist failed
  250. {
  251. LOG((TL_ERROR, "UpdateQueueArray - LineGetQueuelist failed"));
  252. }
  253. // finished with memory block so release
  254. if ( pQueueList != NULL )
  255. ClientFree( pQueueList );
  256. LOG((TL_TRACE, hr, "UpdateQueueArray - exit"));
  257. return hr;
  258. }
  259. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  260. // Class : CACDGroup
  261. // Interface : ITACDGroup
  262. // Method : EnumerateQueues
  263. //
  264. //
  265. //
  266. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  267. STDMETHODIMP CACDGroup::EnumerateQueues(IEnumQueue ** ppEnumQueue)
  268. {
  269. HRESULT hr = S_OK;
  270. LOG((TL_TRACE, "EnumerateQueues - enter"));
  271. if(!TAPIIsBadWritePtr( ppEnumQueue, sizeof(IEnumQueue *) ) )
  272. {
  273. Lock();
  274. UpdateQueueArray();
  275. //
  276. // create the enumerator
  277. //
  278. CComObject< CTapiEnum<IEnumQueue, ITQueue, &IID_IEnumQueue> > * pEnum;
  279. hr = CComObject< CTapiEnum<IEnumQueue, ITQueue, &IID_IEnumQueue> > ::CreateInstance( &pEnum );
  280. if ( SUCCEEDED(hr) )
  281. {
  282. //
  283. // initialize it with our queue list
  284. //
  285. hr = pEnum->Initialize( m_QueueArray );
  286. if ( SUCCEEDED(hr) )
  287. {
  288. // return it
  289. *ppEnumQueue = pEnum;
  290. }
  291. else // failed to initialize
  292. {
  293. LOG((TL_ERROR, "EnumerateQueues - could not initialize enum" ));
  294. pEnum->Release();
  295. }
  296. }
  297. else // failed to create enum
  298. {
  299. LOG((TL_ERROR, "EnumerateQueues - could not create enum" ));
  300. hr = E_POINTER;
  301. }
  302. Unlock();
  303. }
  304. else
  305. {
  306. LOG((TL_ERROR, "EnumerateQueues - bad ppEnumQueue pointer"));
  307. hr = E_POINTER;
  308. }
  309. LOG((TL_TRACE, hr, "EnumerateQueues - exit"));
  310. return hr;
  311. }
  312. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  313. // Class : CACDGroup
  314. // Interface : ITACDGroup
  315. // Method : get_Queues
  316. //
  317. // Return a collection of queues
  318. //
  319. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  320. STDMETHODIMP CACDGroup::get_Queues(VARIANT * pVariant)
  321. {
  322. HRESULT hr = S_OK;
  323. IDispatch * pDisp = NULL;
  324. LOG((TL_TRACE, "get_Queues - enter"));
  325. if (!TAPIIsBadWritePtr( pVariant, sizeof(VARIANT) ) )
  326. {
  327. UpdateQueueArray();
  328. //
  329. // create the collection
  330. //
  331. CComObject< CTapiCollection< ITQueue > > * p;
  332. hr = CComObject< CTapiCollection< ITQueue > >::CreateInstance( &p );
  333. if (SUCCEEDED(hr) )
  334. {
  335. // initialize it with our address list
  336. Lock();
  337. hr = p->Initialize( m_QueueArray );
  338. Unlock();
  339. if ( SUCCEEDED(hr) )
  340. {
  341. // get the IDispatch interface
  342. hr = p->_InternalQueryInterface( IID_IDispatch, (void **) &pDisp );
  343. if ( SUCCEEDED(hr) )
  344. {
  345. // put it in the variant
  346. VariantInit(pVariant);
  347. pVariant->vt = VT_DISPATCH;
  348. pVariant->pdispVal = pDisp;
  349. }
  350. else
  351. {
  352. LOG((TL_ERROR, "get_Queues - could not get IDispatch interface" ));
  353. delete p;
  354. }
  355. }
  356. else
  357. {
  358. LOG((TL_ERROR, "get_Queues - could not initialize collection" ));
  359. delete p;
  360. }
  361. }
  362. else
  363. {
  364. LOG((TL_ERROR, "get_Queues - could not create collection" ));
  365. }
  366. }
  367. else
  368. {
  369. LOG((TL_ERROR, "get_Queues - bad pVariant pointer" ));
  370. hr = E_POINTER;
  371. }
  372. LOG((TL_TRACE, hr, "get_Queues - exit"));
  373. return hr;
  374. }
  375. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  376. // Class : CACDGroup
  377. // Interface : ITACDGroup
  378. // Method : get_Name
  379. //
  380. //
  381. //
  382. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  383. STDMETHODIMP CACDGroup::get_Name(BSTR * Name)
  384. {
  385. HRESULT hr = S_OK;
  386. LOG((TL_TRACE, "Name - enter" ));
  387. if(!TAPIIsBadWritePtr( Name, sizeof(BSTR) ) )
  388. {
  389. if ( active(&hr) )
  390. {
  391. Lock();
  392. *Name = SysAllocString(m_szName);
  393. if (*Name == NULL)
  394. {
  395. hr = E_OUTOFMEMORY;
  396. }
  397. Unlock();
  398. }
  399. }
  400. else
  401. {
  402. LOG((TL_ERROR, "Name - bad Name pointer" ));
  403. hr = E_POINTER;
  404. }
  405. LOG((TL_TRACE, hr, "Name - exit" ));
  406. return hr;
  407. }
  408. /////////////////////////////////////////////////////////////////////////////
  409. // CACDGroup
  410. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  411. // Class : CACDGroup
  412. // Method : FireEvent
  413. //
  414. //
  415. //
  416. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  417. HRESULT CACDGroupEvent::FireEvent(CACDGroup* pACDGroup, ACDGROUP_EVENT Event)
  418. {
  419. HRESULT hr = S_OK;
  420. CComObject<CACDGroupEvent> * pEvent;
  421. IDispatch * pIDispatch;
  422. if ( IsBadReadPtr(pACDGroup, sizeof(CACDGroup)) )
  423. {
  424. STATICLOG((TL_ERROR, "FireEvent - pACDGroup is an invalid pointer"));
  425. _ASSERTE(FALSE);
  426. return E_POINTER;
  427. }
  428. //
  429. // create event
  430. //
  431. hr = CComObject<CACDGroupEvent>::CreateInstance( &pEvent );
  432. if ( SUCCEEDED(hr) )
  433. {
  434. //
  435. // initialize
  436. //
  437. pEvent->m_GroupEvent = Event;
  438. pEvent->m_pGroup= dynamic_cast<ITACDGroup *>(pACDGroup);
  439. pEvent->m_pGroup->AddRef();
  440. //
  441. // get idisp interface
  442. //
  443. hr = pEvent->QueryInterface( IID_IDispatch, (void **)&pIDispatch );
  444. if ( SUCCEEDED(hr) )
  445. {
  446. //
  447. // get callback & fire event
  448. //
  449. CTAPI *pTapi = (pACDGroup->GetAgentHandler() )->GetTapi();
  450. pTapi->Event( TE_ACDGROUP, pIDispatch );
  451. // release stuff
  452. //
  453. pIDispatch->Release();
  454. }
  455. else
  456. {
  457. STATICLOG((TL_ERROR, "FireEvent - Could not get disp interface of ACDGroupEvent object"));
  458. delete pEvent;
  459. }
  460. }
  461. else
  462. {
  463. STATICLOG((TL_ERROR, "FireEvent - Could not create ACDGroupEvent object"));
  464. }
  465. STATICLOG((TL_TRACE, hr, "FireEvent - exit"));
  466. return hr;
  467. }
  468. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  469. // Class : CACDGroup
  470. // Method : FinalRelease
  471. //
  472. //
  473. //
  474. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  475. void CACDGroupEvent::FinalRelease()
  476. {
  477. m_pGroup->Release();
  478. }
  479. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  480. // Class : CACDGroup
  481. // Interface : ITACDGroupEvent
  482. // Method : ACDGroup
  483. //
  484. //
  485. //
  486. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  487. STDMETHODIMP CACDGroupEvent::get_Group(ITACDGroup ** ppGroup)
  488. {
  489. HRESULT hr = S_OK;
  490. LOG((TL_TRACE, "(Event)ACDGroup - enter" ));
  491. if(!TAPIIsBadWritePtr( ppGroup, sizeof(ITACDGroup *) ) )
  492. {
  493. *ppGroup = m_pGroup;
  494. m_pGroup->AddRef();
  495. }
  496. else
  497. {
  498. LOG((TL_ERROR, "(Event)ACDGroup -bad ppGroup pointer"));
  499. hr = E_POINTER;
  500. }
  501. LOG((TL_TRACE, hr, "(Event)ACDGroup - exit"));
  502. return hr;
  503. }
  504. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  505. // Class : CACDGroup
  506. // Interface : ITACDGroupEvent
  507. // Method : Event
  508. //
  509. //
  510. //
  511. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  512. STDMETHODIMP CACDGroupEvent::get_Event(ACDGROUP_EVENT * pEvent)
  513. {
  514. HRESULT hr = S_OK;
  515. LOG((TL_TRACE, "Event - enter" ));
  516. if(!TAPIIsBadWritePtr( pEvent, sizeof(ACDGROUP_EVENT) ) )
  517. {
  518. *pEvent = m_GroupEvent;
  519. }
  520. else
  521. {
  522. LOG((TL_TRACE, "Event - bad pEvent pointer"));
  523. hr = E_POINTER;
  524. }
  525. LOG((TL_TRACE, hr, "Event - exit"));
  526. return hr;
  527. }