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.

1020 lines
26 KiB

  1. //****************************************************************************
  2. //
  3. // Module: ULS.DLL
  4. // File: connpt.cpp
  5. // Content: This file contains the conection point object.
  6. // History:
  7. // Wed 17-Apr-1996 11:13:54 -by- Viroon Touranachun [viroont]
  8. //
  9. // Copyright (c) Microsoft Corporation 1995-1996
  10. //
  11. //****************************************************************************
  12. #include "ulsp.h"
  13. #include "connpt.h"
  14. //****************************************************************************
  15. // CEnumConnectionPoints::CEnumConnectionPoints (void)
  16. //
  17. // History:
  18. // Wed 17-Apr-1996 11:15:18 -by- Viroon Touranachun [viroont]
  19. // Created.
  20. //****************************************************************************
  21. CEnumConnectionPoints::CEnumConnectionPoints (void)
  22. {
  23. cRef = 0;
  24. iIndex = 0;
  25. pcnp = NULL;
  26. return;
  27. }
  28. //****************************************************************************
  29. // CEnumConnectionPoints::~CEnumConnectionPoints (void)
  30. //
  31. // History:
  32. // Wed 17-Apr-1996 11:15:18 -by- Viroon Touranachun [viroont]
  33. // Created.
  34. //****************************************************************************
  35. CEnumConnectionPoints::~CEnumConnectionPoints (void)
  36. {
  37. if (pcnp != NULL)
  38. {
  39. pcnp->Release();
  40. };
  41. return;
  42. }
  43. //****************************************************************************
  44. // STDMETHODIMP
  45. // CEnumConnectionPoints::Init (IConnectionPoint *pcnpInit)
  46. //
  47. // History:
  48. // Wed 17-Apr-1996 11:15:25 -by- Viroon Touranachun [viroont]
  49. // Created.
  50. //****************************************************************************
  51. STDMETHODIMP
  52. CEnumConnectionPoints::Init (IConnectionPoint *pcnpInit)
  53. {
  54. iIndex = 0;
  55. pcnp = pcnpInit;
  56. if (pcnp != NULL)
  57. {
  58. pcnp->AddRef();
  59. };
  60. return S_OK;
  61. }
  62. //****************************************************************************
  63. // STDMETHODIMP
  64. // CEnumConnectionPoints::QueryInterface (REFIID riid, void **ppv)
  65. //
  66. // History:
  67. // Wed 17-Apr-1996 11:15:31 -by- Viroon Touranachun [viroont]
  68. // Created.
  69. //****************************************************************************
  70. STDMETHODIMP
  71. CEnumConnectionPoints::QueryInterface (REFIID riid, void **ppv)
  72. {
  73. if (riid == IID_IEnumConnectionPoints || riid == IID_IUnknown)
  74. {
  75. *ppv = (IEnumConnectionPoints *) this;
  76. AddRef();
  77. return S_OK;
  78. }
  79. else
  80. {
  81. *ppv = NULL;
  82. return ILS_E_NO_INTERFACE;
  83. };
  84. }
  85. //****************************************************************************
  86. // STDMETHODIMP_(ULONG)
  87. // CEnumConnectionPoints::AddRef (void)
  88. //
  89. // History:
  90. // Wed 17-Apr-1996 11:15:37 -by- Viroon Touranachun [viroont]
  91. // Created.
  92. //****************************************************************************
  93. STDMETHODIMP_(ULONG)
  94. CEnumConnectionPoints::AddRef (void)
  95. {
  96. DllLock();
  97. MyDebugMsg ((DM_REFCOUNT, "CEnumConnectionPoints::AddRef: ref=%ld\r\n", cRef));
  98. ::InterlockedIncrement ((LONG *) &cRef);
  99. return cRef;
  100. }
  101. //****************************************************************************
  102. // STDMETHODIMP_(ULONG)
  103. // CEnumConnectionPoints::Release (void)
  104. //
  105. // History:
  106. // Wed 17-Apr-1996 11:15:43 -by- Viroon Touranachun [viroont]
  107. // Created.
  108. //****************************************************************************
  109. STDMETHODIMP_(ULONG)
  110. CEnumConnectionPoints::Release (void)
  111. {
  112. DllRelease();
  113. ASSERT (cRef > 0);
  114. MyDebugMsg ((DM_REFCOUNT, "CEnumConnectionPoints::Release: ref=%ld\r\n", cRef));
  115. if (::InterlockedDecrement ((LONG *) &cRef) == 0)
  116. {
  117. delete this;
  118. return 0;
  119. }
  120. return cRef;
  121. }
  122. //****************************************************************************
  123. // STDMETHODIMP
  124. // CEnumConnectionPoints::Next (ULONG cConnections,
  125. // IConnectionPoint **rgpcn,
  126. // ULONG *pcFetched)
  127. //
  128. // History:
  129. // Wed 17-Apr-1996 11:15:49 -by- Viroon Touranachun [viroont]
  130. // Created.
  131. //****************************************************************************
  132. STDMETHODIMP
  133. CEnumConnectionPoints::Next (ULONG cConnections,
  134. IConnectionPoint **rgpcn,
  135. ULONG *pcFetched)
  136. {
  137. ULONG cCopied;
  138. // Validate the pointer
  139. //
  140. if (rgpcn == NULL)
  141. return ILS_E_POINTER;
  142. // Validate the parameters
  143. //
  144. if ((cConnections == 0) ||
  145. ((cConnections > 1) && (pcFetched == NULL)))
  146. return ILS_E_PARAMETER;
  147. // Check the enumeration index
  148. //
  149. cCopied = 0;
  150. if ((pcnp != NULL) && (iIndex == 0))
  151. {
  152. // Return the only connection point
  153. //
  154. *rgpcn = pcnp;
  155. (*rgpcn)->AddRef();
  156. iIndex++;
  157. cCopied++;
  158. };
  159. // Determine the returned information based on other parameters
  160. //
  161. if (pcFetched != NULL)
  162. {
  163. *pcFetched = cCopied;
  164. };
  165. return (cConnections == cCopied ? S_OK : S_FALSE);
  166. }
  167. //****************************************************************************
  168. // STDMETHODIMP
  169. // CEnumConnectionPoints::Skip (ULONG cConnections)
  170. //
  171. // History:
  172. // Wed 17-Apr-1996 11:15:56 -by- Viroon Touranachun [viroont]
  173. // Created.
  174. //****************************************************************************
  175. STDMETHODIMP
  176. CEnumConnectionPoints::Skip (ULONG cConnections)
  177. {
  178. // Validate the parameters
  179. //
  180. if (cConnections == 0)
  181. return ILS_E_PARAMETER;
  182. // Check the enumeration index limit
  183. //
  184. if ((pcnp == NULL) || (iIndex > 0))
  185. {
  186. return S_FALSE;
  187. }
  188. else
  189. {
  190. // Skip the only elelment
  191. //
  192. iIndex++;
  193. return (cConnections == 1 ? S_OK : S_FALSE);
  194. };
  195. }
  196. //****************************************************************************
  197. // STDMETHODIMP
  198. // CEnumConnectionPoints::Reset (void)
  199. //
  200. // History:
  201. // Wed 17-Apr-1996 11:16:02 -by- Viroon Touranachun [viroont]
  202. // Created.
  203. //****************************************************************************
  204. STDMETHODIMP
  205. CEnumConnectionPoints::Reset (void)
  206. {
  207. iIndex = 0;
  208. return S_OK;
  209. }
  210. //****************************************************************************
  211. // STDMETHODIMP
  212. // CEnumConnectionPoints::Clone(IEnumConnectionPoints **ppEnum)
  213. //
  214. // History:
  215. // Wed 17-Apr-1996 11:16:11 -by- Viroon Touranachun [viroont]
  216. // Created.
  217. //****************************************************************************
  218. STDMETHODIMP
  219. CEnumConnectionPoints::Clone(IEnumConnectionPoints **ppEnum)
  220. {
  221. CEnumConnectionPoints *pecp;
  222. // Validate parameters
  223. //
  224. if (ppEnum == NULL)
  225. {
  226. return ILS_E_POINTER;
  227. };
  228. *ppEnum = NULL;
  229. // Create an enumerator
  230. //
  231. pecp = new CEnumConnectionPoints;
  232. if (pecp == NULL)
  233. return ILS_E_MEMORY;
  234. // Clone the information
  235. //
  236. pecp->iIndex = iIndex;
  237. pecp->pcnp = pcnp;
  238. if (pcnp != NULL)
  239. {
  240. pcnp->AddRef();
  241. };
  242. // Return the cloned enumerator
  243. //
  244. pecp->AddRef();
  245. *ppEnum = pecp;
  246. return S_OK;
  247. }
  248. //****************************************************************************
  249. // CConnectionPoint::CConnectionPoint (const IID *pIID,
  250. // IConnectionPointContainer *pCPCInit)
  251. //
  252. // History:
  253. // Wed 17-Apr-1996 11:16:17 -by- Viroon Touranachun [viroont]
  254. // Created.
  255. //****************************************************************************
  256. CConnectionPoint::CConnectionPoint (const IID *pIID,
  257. IConnectionPointContainer *pCPCInit)
  258. {
  259. cRef = 0;
  260. riid = *pIID;
  261. pCPC = pCPCInit;
  262. dwNextCookie = COOKIE_INIT_VALUE;
  263. cSinkNodes = 0;
  264. pSinkList = NULL;
  265. return;
  266. }
  267. //****************************************************************************
  268. // CConnectionPoint::~CConnectionPoint (void)
  269. //
  270. // History:
  271. // Wed 17-Apr-1996 11:16:17 -by- Viroon Touranachun [viroont]
  272. // Created.
  273. //****************************************************************************
  274. CConnectionPoint::~CConnectionPoint (void)
  275. {
  276. PSINKNODE pSinkNode;
  277. // Traverse the sink list and free each one of them
  278. //
  279. while (pSinkList != NULL)
  280. {
  281. pSinkNode = pSinkList;
  282. pSinkList = pSinkNode->pNext;
  283. pSinkNode->pUnk->Release();
  284. delete pSinkNode;
  285. };
  286. return;
  287. }
  288. //****************************************************************************
  289. // STDMETHODIMP
  290. // CConnectionPoint::QueryInterface (REFIID riid, void **ppv)
  291. //
  292. // History:
  293. // Wed 17-Apr-1996 11:16:23 -by- Viroon Touranachun [viroont]
  294. // Created.
  295. //****************************************************************************
  296. STDMETHODIMP
  297. CConnectionPoint::QueryInterface (REFIID riid, void **ppv)
  298. {
  299. if (riid == IID_IConnectionPoint || riid == IID_IUnknown)
  300. {
  301. *ppv = (IConnectionPoint *) this;
  302. AddRef();
  303. return S_OK;
  304. }
  305. else
  306. {
  307. *ppv = NULL;
  308. return ILS_E_NO_INTERFACE;
  309. };
  310. }
  311. //****************************************************************************
  312. // STDMETHODIMP_(ULONG)
  313. // CConnectionPoint::AddRef (void)
  314. //
  315. // History:
  316. // Wed 17-Apr-1996 11:16:30 -by- Viroon Touranachun [viroont]
  317. // Created.
  318. //****************************************************************************
  319. STDMETHODIMP_(ULONG)
  320. CConnectionPoint::AddRef (void)
  321. {
  322. DllLock();
  323. MyDebugMsg ((DM_REFCOUNT, "CConnectionPoint::AddRef: ref=%ld\r\n", cRef));
  324. ::InterlockedIncrement ((LONG *) &cRef);
  325. return cRef;
  326. }
  327. //****************************************************************************
  328. // STDMETHODIMP_(ULONG)
  329. // CConnectionPoint::Release (void)
  330. //
  331. // History:
  332. // Wed 17-Apr-1996 11:16:36 -by- Viroon Touranachun [viroont]
  333. // Created.
  334. //****************************************************************************
  335. STDMETHODIMP_(ULONG)
  336. CConnectionPoint::Release (void)
  337. {
  338. DllRelease();
  339. ASSERT (cRef > 0);
  340. MyDebugMsg ((DM_REFCOUNT, "CConnectionPoint::Release: ref=%ld\r\n", cRef));
  341. if (::InterlockedDecrement ((LONG *) &cRef) == 0)
  342. {
  343. delete this;
  344. return 0;
  345. }
  346. return cRef;
  347. }
  348. //****************************************************************************
  349. // STDMETHODIMP
  350. // CConnectionPoint::Notify(void *pv, CONN_NOTIFYPROC pfn)
  351. //
  352. // History:
  353. // Wed 17-Apr-1996 11:16:43 -by- Viroon Touranachun [viroont]
  354. // Created.
  355. //****************************************************************************
  356. STDMETHODIMP
  357. CConnectionPoint::Notify(void *pv, CONN_NOTIFYPROC pfn)
  358. {
  359. PSINKNODE pSinkNode, pPrev;
  360. IUnknown *pUnk;
  361. BOOL fNeedClear;
  362. HRESULT hr;
  363. // Enumerate each connection
  364. //
  365. pSinkNode = pSinkList;
  366. hr = S_OK;
  367. fNeedClear = FALSE;
  368. while((pSinkNode != NULL) && (SUCCEEDED(hr)))
  369. {
  370. // Important!! Important!!
  371. // Lock the sink object here. Need to do this in case that the sink
  372. // object calls back to Unadvise and we remove this sink node during
  373. // callback.
  374. //
  375. pSinkNode->uFlags |= SN_LOCKED;
  376. pUnk = pSinkNode->pUnk;
  377. // Calls the sink object
  378. // Note: Do not need to reference the sink object again.
  379. // We already did when Advise was called.
  380. //
  381. hr = (*pfn)(pUnk, pv);
  382. pSinkNode->uFlags &= ~SN_LOCKED;
  383. if (pSinkNode->uFlags & SN_REMOVED)
  384. {
  385. fNeedClear = TRUE;
  386. };
  387. pSinkNode = pSinkNode->pNext;
  388. };
  389. // If there is at least one node to free
  390. //
  391. if (fNeedClear)
  392. {
  393. // Traverse the list for nodes to remove
  394. //
  395. pSinkNode = pSinkList;
  396. pPrev = NULL;
  397. while (pSinkNode != NULL)
  398. {
  399. // Release the sink object, if unadvise
  400. //
  401. if (pSinkNode->uFlags & SN_REMOVED)
  402. {
  403. PSINKNODE pNext;
  404. pNext = pSinkNode->pNext;
  405. if (pPrev == NULL)
  406. {
  407. // This is the head of the list
  408. //
  409. pSinkList = pNext;
  410. }
  411. else
  412. {
  413. pPrev->pNext = pNext;
  414. };
  415. pSinkNode->pUnk->Release();
  416. cSinkNodes--;
  417. delete pSinkNode;
  418. pSinkNode = pNext;
  419. }
  420. else
  421. {
  422. pPrev = pSinkNode;
  423. pSinkNode = pSinkNode->pNext;
  424. };
  425. };
  426. };
  427. return hr;
  428. }
  429. //****************************************************************************
  430. // STDMETHODIMP
  431. // CConnectionPoint::GetConnectionInterface(IID *pIID)
  432. //
  433. // History:
  434. // Wed 17-Apr-1996 11:16:43 -by- Viroon Touranachun [viroont]
  435. // Created.
  436. //****************************************************************************
  437. STDMETHODIMP
  438. CConnectionPoint::GetConnectionInterface(IID *pIID)
  439. {
  440. // Validate the parameter
  441. //
  442. if (pIID == NULL)
  443. return ILS_E_POINTER;
  444. // Support only one connection interface
  445. //
  446. *pIID = riid;
  447. return S_OK;
  448. }
  449. //****************************************************************************
  450. // STDMETHODIMP
  451. // CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer **ppCPC)
  452. //
  453. // History:
  454. // Wed 17-Apr-1996 11:16:49 -by- Viroon Touranachun [viroont]
  455. // Created.
  456. //****************************************************************************
  457. STDMETHODIMP
  458. CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer **ppCPC)
  459. {
  460. // Validate the parameter
  461. //
  462. if (ppCPC == NULL)
  463. return ILS_E_POINTER;
  464. // Return the container and add its reference count
  465. //
  466. *ppCPC = pCPC;
  467. if (pCPC != NULL)
  468. {
  469. // The container is still alive
  470. //
  471. pCPC->AddRef();
  472. return S_OK;
  473. }
  474. else
  475. {
  476. // The container no longer exists
  477. //
  478. return ILS_E_FAIL;
  479. };
  480. }
  481. //****************************************************************************
  482. // STDMETHODIMP
  483. // CConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
  484. //
  485. // History:
  486. // Wed 17-Apr-1996 11:17:01 -by- Viroon Touranachun [viroont]
  487. // Created.
  488. //****************************************************************************
  489. STDMETHODIMP
  490. CConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
  491. {
  492. PSINKNODE pSinkNode;
  493. IUnknown *pSinkInterface;
  494. // Validate the parameter
  495. //
  496. if ((pUnk == NULL) ||
  497. (pdwCookie == NULL))
  498. return ILS_E_PARAMETER;
  499. // Get the sink interface
  500. //
  501. if (FAILED(pUnk->QueryInterface(riid, (void **)&pSinkInterface)))
  502. return CONNECT_E_CANNOTCONNECT;
  503. // Create the sink node
  504. //
  505. pSinkNode = new SINKNODE;
  506. pSinkNode->pNext = pSinkList;
  507. pSinkNode->pUnk = pSinkInterface;
  508. pSinkNode->dwCookie = dwNextCookie;
  509. pSinkNode->uFlags = 0;
  510. *pdwCookie = dwNextCookie;
  511. // Put it in the sink list
  512. //
  513. pSinkList = pSinkNode;
  514. dwNextCookie++;
  515. cSinkNodes++;
  516. return S_OK;
  517. }
  518. //****************************************************************************
  519. // STDMETHODIMP
  520. // CConnectionPoint::Unadvise(DWORD dwCookie)
  521. //
  522. // History:
  523. // Wed 17-Apr-1996 11:17:09 -by- Viroon Touranachun [viroont]
  524. // Created.
  525. //****************************************************************************
  526. STDMETHODIMP
  527. CConnectionPoint::Unadvise(DWORD dwCookie)
  528. {
  529. PSINKNODE pSinkNode, pPrev;
  530. // Search for the matching sink object
  531. //
  532. pPrev = NULL;
  533. pSinkNode = pSinkList;
  534. // Traverse the sink list to find the specified sink object
  535. //
  536. while (pSinkNode != NULL)
  537. {
  538. if (pSinkNode->dwCookie == dwCookie)
  539. {
  540. // Flag to remove
  541. //
  542. pSinkNode->uFlags |= SN_REMOVED;
  543. break;
  544. };
  545. pPrev = pSinkNode;
  546. pSinkNode = pSinkNode->pNext;
  547. };
  548. // Have we found the specified sink object?
  549. //
  550. if (pSinkNode == NULL)
  551. {
  552. // No, return failure
  553. //
  554. return CONNECT_E_NOCONNECTION;
  555. };
  556. // Release the sink object, if not locked
  557. //
  558. if ((pSinkNode->uFlags & SN_REMOVED) &&
  559. !(pSinkNode->uFlags & SN_LOCKED))
  560. {
  561. // Is there a previous node?
  562. //
  563. if (pPrev == NULL)
  564. {
  565. // This is the head of the list
  566. //
  567. pSinkList = pSinkNode->pNext;
  568. }
  569. else
  570. {
  571. pPrev->pNext = pSinkNode->pNext;
  572. };
  573. pSinkNode->pUnk->Release();
  574. cSinkNodes--;
  575. delete pSinkNode;
  576. };
  577. return S_OK;
  578. }
  579. //****************************************************************************
  580. // STDMETHODIMP
  581. // CConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
  582. //
  583. // History:
  584. // Wed 17-Apr-1996 11:17:18 -by- Viroon Touranachun [viroont]
  585. // Created.
  586. //****************************************************************************
  587. STDMETHODIMP
  588. CConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
  589. {
  590. CEnumConnections *pecn;
  591. HRESULT hr;
  592. // Validate parameters
  593. //
  594. if (ppEnum == NULL)
  595. {
  596. return ILS_E_POINTER;
  597. };
  598. // Assume failure
  599. //
  600. *ppEnum = NULL;
  601. // Create an enumerator
  602. //
  603. pecn = new CEnumConnections;
  604. if (pecn == NULL)
  605. return ILS_E_MEMORY;
  606. // Initialize the enumerator
  607. //
  608. hr = pecn->Init(pSinkList, cSinkNodes);
  609. if (FAILED(hr))
  610. {
  611. delete pecn;
  612. return hr;
  613. };
  614. pecn->AddRef();
  615. *ppEnum = pecn;
  616. return S_OK;
  617. }
  618. //****************************************************************************
  619. // CEnumConnections::CEnumConnections(void)
  620. //
  621. // History:
  622. // Wed 17-Apr-1996 11:17:25 -by- Viroon Touranachun [viroont]
  623. // Created.
  624. //****************************************************************************
  625. CEnumConnections::CEnumConnections(void)
  626. {
  627. cRef = 0;
  628. iIndex = 0;
  629. cConnections = 0;
  630. pConnectData = NULL;
  631. return;
  632. }
  633. //****************************************************************************
  634. // CEnumConnections::~CEnumConnections(void)
  635. //
  636. // History:
  637. // Wed 17-Apr-1996 11:17:25 -by- Viroon Touranachun [viroont]
  638. // Created.
  639. //****************************************************************************
  640. CEnumConnections::~CEnumConnections(void)
  641. {
  642. if (pConnectData != NULL)
  643. {
  644. UINT i;
  645. for (i = 0; i < cConnections; i++)
  646. {
  647. pConnectData[i].pUnk->Release();
  648. };
  649. delete [] pConnectData;
  650. };
  651. return;
  652. }
  653. //****************************************************************************
  654. // STDMETHODIMP
  655. // CEnumConnections::Init(PSINKNODE pSinkList, ULONG cSinkNodes)
  656. //
  657. // History:
  658. // Wed 17-Apr-1996 11:17:34 -by- Viroon Touranachun [viroont]
  659. // Created.
  660. //****************************************************************************
  661. STDMETHODIMP
  662. CEnumConnections::Init(PSINKNODE pSinkList, ULONG cSinkNodes)
  663. {
  664. HRESULT hr = S_OK;
  665. iIndex = 0;
  666. cConnections = 0;
  667. pConnectData = NULL;
  668. // Snapshot the connection list
  669. //
  670. if (cSinkNodes > 0)
  671. {
  672. UINT i;
  673. pConnectData = new CONNECTDATA[cSinkNodes];
  674. if (pConnectData != NULL)
  675. {
  676. for (i = 0; i < cSinkNodes && pSinkList != NULL; i++)
  677. {
  678. if (!(pSinkList->uFlags & SN_REMOVED))
  679. {
  680. pConnectData[cConnections].pUnk = pSinkList->pUnk;
  681. pConnectData[cConnections].pUnk->AddRef();
  682. pConnectData[cConnections].dwCookie = pSinkList->dwCookie;
  683. cConnections++;
  684. };
  685. pSinkList = pSinkList->pNext;
  686. };
  687. }
  688. else
  689. {
  690. hr = ILS_E_MEMORY;
  691. };
  692. };
  693. return hr;
  694. }
  695. //****************************************************************************
  696. // STDMETHODIMP
  697. // CEnumConnections::QueryInterface (REFIID riid, void **ppv)
  698. //
  699. // History:
  700. // Wed 17-Apr-1996 11:17:40 -by- Viroon Touranachun [viroont]
  701. // Created.
  702. //****************************************************************************
  703. STDMETHODIMP
  704. CEnumConnections::QueryInterface (REFIID riid, void **ppv)
  705. {
  706. if (riid == IID_IEnumConnections || riid == IID_IUnknown)
  707. {
  708. *ppv = (IEnumConnections *) this;
  709. AddRef();
  710. return S_OK;
  711. }
  712. else
  713. {
  714. *ppv = NULL;
  715. return ILS_E_NO_INTERFACE;
  716. };
  717. }
  718. //****************************************************************************
  719. // STDMETHODIMP_(ULONG)
  720. // CEnumConnections::AddRef (void)
  721. //
  722. // History:
  723. // Wed 17-Apr-1996 11:17:49 -by- Viroon Touranachun [viroont]
  724. // Created.
  725. //****************************************************************************
  726. STDMETHODIMP_(ULONG)
  727. CEnumConnections::AddRef (void)
  728. {
  729. DllLock();
  730. MyDebugMsg ((DM_REFCOUNT, "CEnumConnections::AddRef: ref=%ld\r\n", cRef));
  731. ::InterlockedIncrement ((LONG *) &cRef);
  732. return cRef;
  733. }
  734. //****************************************************************************
  735. // STDMETHODIMP_(ULONG)
  736. // CEnumConnections::Release (void)
  737. //
  738. // History:
  739. // Wed 17-Apr-1996 11:17:59 -by- Viroon Touranachun [viroont]
  740. // Created.
  741. //****************************************************************************
  742. STDMETHODIMP_(ULONG)
  743. CEnumConnections::Release (void)
  744. {
  745. DllRelease();
  746. ASSERT (cRef > 0);
  747. MyDebugMsg ((DM_REFCOUNT, "CEnumConnections::Release: ref=%ld\r\n", cRef));
  748. if (::InterlockedDecrement ((LONG *) &cRef) == 0)
  749. {
  750. delete this;
  751. return 0;
  752. }
  753. return cRef;
  754. }
  755. //****************************************************************************
  756. // STDMETHODIMP
  757. // CEnumConnections::Next (ULONG cConnectionDatas, CONNECTDATA *rgpcd,
  758. // ULONG *pcFetched)
  759. //
  760. // History:
  761. // Wed 17-Apr-1996 11:18:07 -by- Viroon Touranachun [viroont]
  762. // Created.
  763. //****************************************************************************
  764. STDMETHODIMP
  765. CEnumConnections::Next (ULONG cConnectDatas, CONNECTDATA *rgpcd,
  766. ULONG *pcFetched)
  767. {
  768. CONNECTDATA *pConnect;
  769. ULONG cCopied;
  770. // Validate the pointer
  771. //
  772. if (rgpcd == NULL)
  773. return ILS_E_POINTER;
  774. // Validate the parameters
  775. //
  776. if ((cConnectDatas == 0) ||
  777. ((cConnectDatas > 1) && (pcFetched == NULL)))
  778. return ILS_E_PARAMETER;
  779. // Check the enumeration index
  780. //
  781. pConnect = &pConnectData[iIndex];
  782. for (cCopied = 0; iIndex < cConnections && cCopied < cConnectDatas; cCopied++)
  783. {
  784. rgpcd[cCopied] = *pConnect;
  785. rgpcd[cCopied].pUnk->AddRef();
  786. iIndex++;
  787. pConnect++;
  788. };
  789. // Determine the returned information based on other parameters
  790. //
  791. if (pcFetched != NULL)
  792. {
  793. *pcFetched = cCopied;
  794. };
  795. return (cConnectDatas == cCopied ? S_OK : S_FALSE);
  796. }
  797. //****************************************************************************
  798. // STDMETHODIMP
  799. // CEnumConnections::Skip (ULONG cConnectDatas)
  800. //
  801. // History:
  802. // Wed 17-Apr-1996 11:18:15 -by- Viroon Touranachun [viroont]
  803. // Created.
  804. //****************************************************************************
  805. STDMETHODIMP
  806. CEnumConnections::Skip (ULONG cConnectDatas)
  807. {
  808. // Validate the parameters
  809. //
  810. if (cConnectDatas == 0)
  811. return ILS_E_PARAMETER;
  812. // Check the enumeration index limit
  813. //
  814. if ((iIndex+cConnectDatas) >= cConnections)
  815. {
  816. iIndex = cConnections;
  817. return S_FALSE;
  818. }
  819. else
  820. {
  821. // Skip as requested
  822. //
  823. iIndex += cConnectDatas;
  824. return S_OK;
  825. };
  826. }
  827. //****************************************************************************
  828. // STDMETHODIMP
  829. // CEnumConnections::Reset (void)
  830. //
  831. // History:
  832. // Wed 17-Apr-1996 11:18:22 -by- Viroon Touranachun [viroont]
  833. // Created.
  834. //****************************************************************************
  835. STDMETHODIMP
  836. CEnumConnections::Reset (void)
  837. {
  838. iIndex = 0;
  839. return S_OK;
  840. }
  841. //****************************************************************************
  842. // STDMETHODIMP
  843. // CEnumConnections::Clone(IEnumConnections **ppEnum)
  844. //
  845. // History:
  846. // Wed 17-Apr-1996 11:18:29 -by- Viroon Touranachun [viroont]
  847. // Created.
  848. //****************************************************************************
  849. STDMETHODIMP
  850. CEnumConnections::Clone(IEnumConnections **ppEnum)
  851. {
  852. CEnumConnections *pecn;
  853. CONNECTDATA *pConnectDataClone;
  854. UINT i;
  855. // Validate parameters
  856. //
  857. if (ppEnum == NULL)
  858. {
  859. return ILS_E_POINTER;
  860. };
  861. *ppEnum = NULL;
  862. // Create an enumerator
  863. //
  864. pecn = new CEnumConnections;
  865. if (pecn == NULL)
  866. return ILS_E_MEMORY;
  867. // Clone the information
  868. //
  869. pConnectDataClone = new CONNECTDATA[cConnections];
  870. if (pConnectDataClone == NULL)
  871. {
  872. delete pecn;
  873. return ILS_E_MEMORY;
  874. };
  875. // Clone the connect data list
  876. //
  877. for (i = 0; i < cConnections; i++)
  878. {
  879. pConnectDataClone[i] = pConnectData[i];
  880. pConnectDataClone[i].pUnk->AddRef();
  881. };
  882. pecn->iIndex = iIndex;
  883. pecn->cConnections = cConnections;
  884. // Return the cloned enumerator
  885. //
  886. pecn->AddRef();
  887. *ppEnum = pecn;
  888. return S_OK;
  889. }