Source code of Windows XP (NT5)
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.

316 lines
6.4 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. InterlockedDecrement(&m_cRef);
  79. if (0L!=m_cRef)
  80. return m_cRef;
  81. delete this;
  82. return 0;
  83. }
  84. //***************************************************************************
  85. //
  86. // SCODE CQualSetEnumVar::Reset
  87. //
  88. // DESCRIPTION:
  89. //
  90. // Reset the enumeration
  91. //
  92. // PARAMETERS:
  93. //
  94. // RETURN VALUES:
  95. //
  96. // S_OK success
  97. //
  98. //***************************************************************************
  99. HRESULT CQualSetEnumVar::Reset ()
  100. {
  101. m_pos = 0;
  102. return S_OK;
  103. }
  104. //***************************************************************************
  105. //
  106. // SCODE CQualSetEnumVar::Next
  107. //
  108. // DESCRIPTION:
  109. //
  110. // Get the next object in the enumeration
  111. //
  112. // PARAMETERS:
  113. //
  114. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  115. // indefinite)
  116. // ppObject On return may contain the next element (if any)
  117. //
  118. // RETURN VALUES:
  119. //
  120. // S_OK success (all requested elements returned)
  121. // S_FALSE otherwise
  122. //
  123. //***************************************************************************
  124. HRESULT CQualSetEnumVar::Next (
  125. ULONG cElements,
  126. VARIANT FAR* pVar,
  127. ULONG FAR* pcElementFetched
  128. )
  129. {
  130. HRESULT hr = S_OK;
  131. ULONG l2 = 0;
  132. if (NULL != pcElementFetched)
  133. *pcElementFetched = 0;
  134. if (NULL != pVar)
  135. {
  136. for (ULONG l = 0; l < cElements; l++)
  137. VariantInit (&pVar [l]);
  138. if (m_pQualifierSet)
  139. {
  140. // Retrieve the next cElements elements.
  141. if (SeekCurrentPosition ())
  142. {
  143. for (l2 = 0; l2 < cElements; l2++)
  144. {
  145. HRESULT hRes2;
  146. ISWbemQualifier *pQualifier = NULL;
  147. if (SUCCEEDED(hRes2 = m_pQualifierSet->Next (0, &pQualifier)))
  148. {
  149. if (NULL == pQualifier)
  150. {
  151. break;
  152. }
  153. else
  154. {
  155. // Set the object into the variant array; note that pObject
  156. // has been addref'd as a result of the Next() call above
  157. pVar[l2].vt = VT_DISPATCH;
  158. pVar[l2].pdispVal = pQualifier;
  159. m_pos++;
  160. }
  161. }
  162. else
  163. break;
  164. }
  165. if (NULL != pcElementFetched)
  166. *pcElementFetched = l2;
  167. }
  168. }
  169. }
  170. return (l2 < cElements) ? S_FALSE : S_OK;
  171. }
  172. //***************************************************************************
  173. //
  174. // SCODE CQualSetEnumVar::Clone
  175. //
  176. // DESCRIPTION:
  177. //
  178. // Create a copy of this enumeration
  179. //
  180. // PARAMETERS:
  181. //
  182. // ppEnum on successful return addresses the clone
  183. //
  184. // RETURN VALUES:
  185. //
  186. // S_OK success
  187. // E_OUTOFMEMORY insufficient memory to complete operation
  188. //
  189. //***************************************************************************
  190. HRESULT CQualSetEnumVar::Clone (
  191. IEnumVARIANT **ppEnum
  192. )
  193. {
  194. HRESULT hr = E_FAIL;
  195. if (NULL != ppEnum)
  196. {
  197. *ppEnum = NULL;
  198. if (m_pQualifierSet)
  199. {
  200. CQualSetEnumVar *pEnum = new CQualSetEnumVar (m_pQualifierSet, m_pos);
  201. if (!pEnum)
  202. hr = WBEM_E_OUT_OF_MEMORY;
  203. else if (FAILED(hr = pEnum->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum)))
  204. delete pEnum;
  205. }
  206. }
  207. return hr;
  208. }
  209. //***************************************************************************
  210. //
  211. // SCODE CQualSetEnumVar::Skip
  212. //
  213. // DESCRIPTION:
  214. //
  215. // Skips some elements in this enumeration
  216. //
  217. // PARAMETERS:
  218. //
  219. // ppEnum on successful return addresses the clone
  220. //
  221. // RETURN VALUES:
  222. //
  223. // S_OK success
  224. // S_FALSE end of sequence reached prematurely
  225. //
  226. //***************************************************************************
  227. HRESULT CQualSetEnumVar::Skip(
  228. ULONG cElements
  229. )
  230. {
  231. HRESULT hr = S_FALSE;
  232. long count = 0;
  233. m_pQualifierSet->get_Count (&count);
  234. if (((ULONG) count) >= cElements + m_pos)
  235. {
  236. hr = S_OK;
  237. m_pos += cElements;
  238. }
  239. else
  240. m_pos = count;
  241. return hr;
  242. }
  243. //***************************************************************************
  244. //
  245. // SCODE CQualSetEnumVar::SeekCurrentPosition
  246. //
  247. // DESCRIPTION:
  248. //
  249. // Iterate to current position. Somewhat painful as there is no
  250. // underlying iterator so we have to reset and then step. Note that we
  251. // assume that the access to this iterator is apartment-threaded.
  252. //
  253. // PARAMETERS:
  254. //
  255. // ppEnum on successful return addresses the clone
  256. //
  257. // RETURN VALUES:
  258. //
  259. // S_OK success
  260. // S_FALSE end of sequence reached prematurely
  261. //
  262. //***************************************************************************
  263. bool CQualSetEnumVar::SeekCurrentPosition ()
  264. {
  265. ISWbemQualifier *pDummyObject = NULL;
  266. m_pQualifierSet->BeginEnumeration ();
  267. // Traverse to the current position
  268. ULONG i = 0;
  269. for (; i < m_pos; i++)
  270. {
  271. if (WBEM_S_NO_ERROR != m_pQualifierSet->Next (0, &pDummyObject))
  272. break;
  273. else
  274. pDummyObject->Release ();
  275. }
  276. return (i == m_pos);
  277. }