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.

313 lines
6.3 KiB

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