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.

232 lines
5.2 KiB

  1. /*****************************************************************************\
  2. * MODULE: enum.cpp
  3. *
  4. * PURPOSE: Implementation of COM interface for BidiSpooler
  5. *
  6. * Copyright (C) 2000 Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 03/09/00 Weihai Chen (weihaic) Created
  11. *
  12. \*****************************************************************************/
  13. #include "precomp.h"
  14. #include "priv.h"
  15. TBidiRequestContainerEnum::TBidiRequestContainerEnum (
  16. TBidiRequestContainer & refContainer,
  17. TReqInterfaceList & refReqList):
  18. m_refReqList (refReqList),
  19. m_refContainer (refContainer),
  20. m_cRef (1)
  21. {
  22. m_refContainer.AddRef ();
  23. TAutoCriticalSection CritSec (m_refReqList);
  24. if (CritSec.bValid ()) {
  25. m_pHead = m_refReqList.GetHead();
  26. m_pCurrent = m_pHead;
  27. m_bValid = TRUE;
  28. }
  29. else
  30. m_bValid = FALSE;
  31. }
  32. TBidiRequestContainerEnum::TBidiRequestContainerEnum (
  33. TBidiRequestContainerEnum & refEnum):
  34. m_refReqList (refEnum.m_refReqList),
  35. m_refContainer (refEnum.m_refContainer),
  36. m_cRef (1)
  37. {
  38. m_refContainer.AddRef ();
  39. TAutoCriticalSection CritSec (m_refReqList);
  40. if (CritSec.bValid ()) {
  41. m_pHead = refEnum.m_pHead;
  42. m_pCurrent = refEnum.m_pCurrent;
  43. m_bValid = TRUE;
  44. }
  45. else
  46. m_bValid = FALSE;
  47. }
  48. TBidiRequestContainerEnum::~TBidiRequestContainerEnum ()
  49. {
  50. DBGMSG(DBG_TRACE,("TBidiRequestContainerEnum Destory Self\n"));
  51. m_refContainer.Release ();
  52. }
  53. STDMETHODIMP
  54. TBidiRequestContainerEnum::QueryInterface (
  55. REFIID iid,
  56. void** ppv)
  57. {
  58. HRESULT hr = S_OK;
  59. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum QI\n"));
  60. if (iid == IID_IUnknown) {
  61. *ppv = static_cast<IUnknown*>(this) ;
  62. }
  63. else if (iid == IID_IEnumUnknown) {
  64. *ppv = static_cast<IEnumUnknown*>(this) ;
  65. }
  66. else {
  67. *ppv = NULL ;
  68. hr = E_NOINTERFACE ;
  69. }
  70. if (*ppv) {
  71. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  72. }
  73. DBGMSG(DBG_TRACE,("Leave TBidiRequestContainerEnum QI hr=%x\n", hr));
  74. return hr ;
  75. }
  76. STDMETHODIMP_ (ULONG)
  77. TBidiRequestContainerEnum::AddRef ()
  78. {
  79. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::AddRef ref= %d\n", m_cRef));
  80. // We add a reference to the container so that the container won't
  81. // delete the list where there is an outstadning enummeration
  82. //
  83. return InterlockedIncrement(&m_cRef) ;
  84. }
  85. STDMETHODIMP_ (ULONG)
  86. TBidiRequestContainerEnum::Release ()
  87. {
  88. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Release ref= %d\n", m_cRef));
  89. if (InterlockedDecrement(&m_cRef) == 0)
  90. {
  91. delete this ;
  92. return 0 ;
  93. }
  94. return m_cRef ;
  95. }
  96. STDMETHODIMP
  97. TBidiRequestContainerEnum::Next (
  98. IN ULONG celt,
  99. OUT IUnknown ** rgelt,
  100. OUT ULONG * pceltFetched)
  101. {
  102. HRESULT hr;
  103. DWORD dwCount = 0;
  104. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Next\n"));
  105. if (m_bValid) {
  106. if (rgelt && pceltFetched) {
  107. TAutoCriticalSection CritSec (m_refReqList);
  108. if (CritSec.bValid ()) {
  109. while (m_pCurrent && dwCount < celt) {
  110. TBidiRequestInterfaceData * pData = m_pCurrent->GetData ();
  111. *rgelt = (IUnknown *) pData->GetInterface();
  112. (*rgelt++)->AddRef ();
  113. m_pCurrent = m_pCurrent->GetNext ();
  114. dwCount++;
  115. }
  116. *pceltFetched = dwCount;
  117. hr = S_OK;
  118. }
  119. else
  120. hr = LastError2HRESULT ();
  121. }
  122. else
  123. hr = E_POINTER;
  124. }
  125. else
  126. hr = E_HANDLE;
  127. return hr;
  128. }
  129. STDMETHODIMP
  130. TBidiRequestContainerEnum::Skip (
  131. IN ULONG celt)
  132. {
  133. HRESULT hr;
  134. DWORD dwCount = 0;
  135. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Skip\n"));
  136. if (m_bValid) {
  137. TAutoCriticalSection CritSec (m_refReqList);
  138. if (CritSec.bValid ()) {
  139. while (m_pCurrent && dwCount < celt) {
  140. m_pCurrent = m_pCurrent->GetNext ();
  141. dwCount++;
  142. }
  143. hr = S_OK;
  144. }
  145. else
  146. hr = LastError2HRESULT ();
  147. }
  148. else
  149. hr = E_HANDLE;
  150. return hr;
  151. }
  152. STDMETHODIMP
  153. TBidiRequestContainerEnum::Reset(void)
  154. {
  155. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Reset\n"));
  156. if (m_bValid) {
  157. m_pCurrent = m_pHead;
  158. return S_OK;
  159. }
  160. else
  161. return E_HANDLE;
  162. }
  163. STDMETHODIMP
  164. TBidiRequestContainerEnum::Clone(
  165. OUT IEnumUnknown ** ppenum)
  166. {
  167. HRESULT hr;
  168. DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Clone\n"));
  169. if (m_bValid) {
  170. hr = PrivCreateComponent <TBidiRequestContainerEnum> (
  171. new TBidiRequestContainerEnum (*this),
  172. IID_IEnumUnknown, (void **)ppenum);
  173. }
  174. else
  175. hr = E_HANDLE;
  176. return hr;
  177. }