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.

320 lines
6.8 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // CONTENUM.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of IEnumVARIANT for iterators over ISWbemQualifierSet
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CQualSetEnumVar::CQualSetEnumVar
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CQualSetEnumVar::CQualSetEnumVar(CSWbemQualifierSet *pQualSet,
  23. ULONG initialPos)
  24. {
  25. m_cRef = 0;
  26. m_pos = initialPos;
  27. m_pQualifierSet = pQualSet;
  28. m_pQualifierSet->AddRef ();
  29. InterlockedIncrement(&g_cObj);
  30. }
  31. //***************************************************************************
  32. //
  33. // CQualSetEnumVar::~CQualSetEnumVar
  34. //
  35. // DESCRIPTION:
  36. //
  37. // Destructor.
  38. //
  39. //***************************************************************************
  40. CQualSetEnumVar::~CQualSetEnumVar(void)
  41. {
  42. InterlockedDecrement(&g_cObj);
  43. if (m_pQualifierSet)
  44. m_pQualifierSet->Release ();
  45. }
  46. //***************************************************************************
  47. // HRESULT CQualSetEnumVar::QueryInterface
  48. // long CQualSetEnumVar::AddRef
  49. // long CQualSetEnumVar::Release
  50. //
  51. // DESCRIPTION:
  52. //
  53. // Standard Com IUNKNOWN functions.
  54. //
  55. //***************************************************************************
  56. STDMETHODIMP CQualSetEnumVar::QueryInterface (
  57. IN REFIID riid,
  58. OUT LPVOID *ppv
  59. )
  60. {
  61. *ppv=NULL;
  62. if (IID_IUnknown==riid || IID_IEnumVARIANT==riid)
  63. *ppv=this;
  64. if (NULL!=*ppv)
  65. {
  66. ((LPUNKNOWN)*ppv)->AddRef();
  67. return NOERROR;
  68. }
  69. return ResultFromScode(E_NOINTERFACE);
  70. }
  71. STDMETHODIMP_(ULONG) CQualSetEnumVar::AddRef(void)
  72. {
  73. InterlockedIncrement(&m_cRef);
  74. return m_cRef;
  75. }
  76. STDMETHODIMP_(ULONG) CQualSetEnumVar::Release(void)
  77. {
  78. LONG cRef = InterlockedDecrement(&m_cRef);
  79. if (0 != cRef)
  80. {
  81. _ASSERT(cRef > 0);
  82. return cRef;
  83. }
  84. delete this;
  85. return 0;
  86. }
  87. //***************************************************************************
  88. //
  89. // SCODE CQualSetEnumVar::Reset
  90. //
  91. // DESCRIPTION:
  92. //
  93. // Reset the enumeration
  94. //
  95. // PARAMETERS:
  96. //
  97. // RETURN VALUES:
  98. //
  99. // S_OK success
  100. //
  101. //***************************************************************************
  102. HRESULT CQualSetEnumVar::Reset ()
  103. {
  104. m_pos = 0;
  105. return S_OK;
  106. }
  107. //***************************************************************************
  108. //
  109. // SCODE CQualSetEnumVar::Next
  110. //
  111. // DESCRIPTION:
  112. //
  113. // Get the next object in the enumeration
  114. //
  115. // PARAMETERS:
  116. //
  117. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  118. // indefinite)
  119. // ppObject On return may contain the next element (if any)
  120. //
  121. // RETURN VALUES:
  122. //
  123. // S_OK success (all requested elements returned)
  124. // S_FALSE otherwise
  125. //
  126. //***************************************************************************
  127. HRESULT CQualSetEnumVar::Next (
  128. ULONG cElements,
  129. VARIANT FAR* pVar,
  130. ULONG FAR* pcElementFetched
  131. )
  132. {
  133. HRESULT hr = S_OK;
  134. ULONG l2 = 0;
  135. if (NULL != pcElementFetched)
  136. *pcElementFetched = 0;
  137. if (NULL != pVar)
  138. {
  139. for (ULONG l = 0; l < cElements; l++)
  140. VariantInit (&pVar [l]);
  141. if (m_pQualifierSet)
  142. {
  143. // Retrieve the next cElements elements.
  144. if (SeekCurrentPosition ())
  145. {
  146. for (l2 = 0; l2 < cElements; l2++)
  147. {
  148. HRESULT hRes2;
  149. ISWbemQualifier *pQualifier = NULL;
  150. if (SUCCEEDED(hRes2 = m_pQualifierSet->Next (0, &pQualifier)))
  151. {
  152. if (NULL == pQualifier)
  153. {
  154. break;
  155. }
  156. else
  157. {
  158. // Set the object into the variant array; note that pObject
  159. // has been addref'd as a result of the Next() call above
  160. pVar[l2].vt = VT_DISPATCH;
  161. pVar[l2].pdispVal = pQualifier;
  162. m_pos++;
  163. }
  164. }
  165. else
  166. break;
  167. }
  168. if (NULL != pcElementFetched)
  169. *pcElementFetched = l2;
  170. }
  171. }
  172. }
  173. return (l2 < cElements) ? S_FALSE : S_OK;
  174. }
  175. //***************************************************************************
  176. //
  177. // SCODE CQualSetEnumVar::Clone
  178. //
  179. // DESCRIPTION:
  180. //
  181. // Create a copy of this enumeration
  182. //
  183. // PARAMETERS:
  184. //
  185. // ppEnum on successful return addresses the clone
  186. //
  187. // RETURN VALUES:
  188. //
  189. // S_OK success
  190. // E_OUTOFMEMORY insufficient memory to complete operation
  191. //
  192. //***************************************************************************
  193. HRESULT CQualSetEnumVar::Clone (
  194. IEnumVARIANT **ppEnum
  195. )
  196. {
  197. HRESULT hr = E_FAIL;
  198. if (NULL != ppEnum)
  199. {
  200. *ppEnum = NULL;
  201. if (m_pQualifierSet)
  202. {
  203. CQualSetEnumVar *pEnum = new CQualSetEnumVar (m_pQualifierSet, m_pos);
  204. if (!pEnum)
  205. hr = WBEM_E_OUT_OF_MEMORY;
  206. else if (FAILED(hr = pEnum->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum)))
  207. delete pEnum;
  208. }
  209. }
  210. return hr;
  211. }
  212. //***************************************************************************
  213. //
  214. // SCODE CQualSetEnumVar::Skip
  215. //
  216. // DESCRIPTION:
  217. //
  218. // Skips some elements in this enumeration
  219. //
  220. // PARAMETERS:
  221. //
  222. // ppEnum on successful return addresses the clone
  223. //
  224. // RETURN VALUES:
  225. //
  226. // S_OK success
  227. // S_FALSE end of sequence reached prematurely
  228. //
  229. //***************************************************************************
  230. HRESULT CQualSetEnumVar::Skip(
  231. ULONG cElements
  232. )
  233. {
  234. HRESULT hr = S_FALSE;
  235. long count = 0;
  236. m_pQualifierSet->get_Count (&count);
  237. if (((ULONG) count) >= cElements + m_pos)
  238. {
  239. hr = S_OK;
  240. m_pos += cElements;
  241. }
  242. else
  243. m_pos = count;
  244. return hr;
  245. }
  246. //***************************************************************************
  247. //
  248. // SCODE CQualSetEnumVar::SeekCurrentPosition
  249. //
  250. // DESCRIPTION:
  251. //
  252. // Iterate to current position. Somewhat painful as there is no
  253. // underlying iterator so we have to reset and then step. Note that we
  254. // assume that the access to this iterator is apartment-threaded.
  255. //
  256. // PARAMETERS:
  257. //
  258. // ppEnum on successful return addresses the clone
  259. //
  260. // RETURN VALUES:
  261. //
  262. // S_OK success
  263. // S_FALSE end of sequence reached prematurely
  264. //
  265. //***************************************************************************
  266. bool CQualSetEnumVar::SeekCurrentPosition ()
  267. {
  268. ISWbemQualifier *pDummyObject = NULL;
  269. m_pQualifierSet->BeginEnumeration ();
  270. // Traverse to the current position
  271. ULONG i = 0;
  272. for (; i < m_pos; i++)
  273. {
  274. if (WBEM_S_NO_ERROR != m_pQualifierSet->Next (0, &pDummyObject))
  275. break;
  276. else
  277. pDummyObject->Release ();
  278. }
  279. return (i == m_pos);
  280. }