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.

321 lines
6.6 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // CONTVAR.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of IEnumVARIANT for iterators over
  10. // ISWbemNamedValueSet
  11. //
  12. //***************************************************************************
  13. #include "precomp.h"
  14. //***************************************************************************
  15. //
  16. // CContextEnumVar::CContextEnumVar
  17. //
  18. // DESCRIPTION:
  19. //
  20. // Constructor.
  21. //
  22. //***************************************************************************
  23. CContextEnumVar::CContextEnumVar(CSWbemNamedValueSet *pContext, ULONG initialPos)
  24. {
  25. m_cRef = 0;
  26. m_pos = initialPos;
  27. m_pContext = pContext;
  28. m_pContext->AddRef ();
  29. InterlockedIncrement(&g_cObj);
  30. }
  31. //***************************************************************************
  32. //
  33. // CContextEnumVar::~CContextEnumVar
  34. //
  35. // DESCRIPTION:
  36. //
  37. // Destructor.
  38. //
  39. //***************************************************************************
  40. CContextEnumVar::~CContextEnumVar(void)
  41. {
  42. InterlockedDecrement(&g_cObj);
  43. if (m_pContext)
  44. m_pContext->Release ();
  45. }
  46. //***************************************************************************
  47. // HRESULT CContextEnumVar::QueryInterface
  48. // long CContextEnumVar::AddRef
  49. // long CContextEnumVar::Release
  50. //
  51. // DESCRIPTION:
  52. //
  53. // Standard Com IUNKNOWN functions.
  54. //
  55. //***************************************************************************
  56. STDMETHODIMP CContextEnumVar::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) CContextEnumVar::AddRef(void)
  72. {
  73. InterlockedIncrement(&m_cRef);
  74. return m_cRef;
  75. }
  76. STDMETHODIMP_(ULONG) CContextEnumVar::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 CContextEnumVar::Reset
  90. //
  91. // DESCRIPTION:
  92. //
  93. // Reset the enumeration
  94. //
  95. // PARAMETERS:
  96. //
  97. // RETURN VALUES:
  98. //
  99. // S_OK success
  100. // S_FALSE otherwise
  101. //
  102. //***************************************************************************
  103. HRESULT CContextEnumVar::Reset ()
  104. {
  105. m_pos = 0;
  106. return S_OK;
  107. }
  108. //***************************************************************************
  109. //
  110. // SCODE CContextEnumVar::Next
  111. //
  112. // DESCRIPTION:
  113. //
  114. // Get the next object in the enumeration
  115. //
  116. // PARAMETERS:
  117. //
  118. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  119. // indefinite)
  120. // ppObject On return may contain the next element (if any)
  121. //
  122. // RETURN VALUES:
  123. //
  124. // S_OK success
  125. // S_FALSE otherwise
  126. //
  127. //***************************************************************************
  128. HRESULT CContextEnumVar::Next (
  129. ULONG cElements,
  130. VARIANT FAR* pVar,
  131. ULONG FAR* pcElementFetched
  132. )
  133. {
  134. HRESULT hr = S_OK;
  135. ULONG l2 = 0;
  136. if (NULL != pcElementFetched)
  137. *pcElementFetched = 0;
  138. if (NULL != pVar)
  139. {
  140. for (ULONG l = 0; l < cElements; l++)
  141. VariantInit (&pVar [l]);
  142. if (m_pContext)
  143. {
  144. // Retrieve the next cElements elements.
  145. if (SeekCurrentPosition ())
  146. {
  147. for (l2 = 0; l2 < cElements; l2++)
  148. {
  149. ISWbemNamedValue *pObject = NULL;
  150. if (SUCCEEDED(m_pContext->Next (0, &pObject)))
  151. {
  152. if (NULL == pObject)
  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 = pObject;
  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 CContextEnumVar::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_FAIL otherwise
  191. //
  192. //***************************************************************************
  193. HRESULT CContextEnumVar::Clone (
  194. IEnumVARIANT **ppEnum
  195. )
  196. {
  197. HRESULT hr = E_FAIL;
  198. if (NULL != ppEnum)
  199. {
  200. *ppEnum = NULL;
  201. if (m_pContext)
  202. {
  203. CContextEnumVar *pEnum = new CContextEnumVar (m_pContext, 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 CContextEnumVar::Skip
  215. //
  216. // DESCRIPTION:
  217. //
  218. // Create a copy of 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 CContextEnumVar::Skip(
  231. ULONG cElements
  232. )
  233. {
  234. HRESULT hr = S_FALSE;
  235. long count = 0;
  236. m_pContext->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 CContextEnumVar::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 CContextEnumVar::SeekCurrentPosition ()
  267. {
  268. ISWbemNamedValue *pDummyObject = NULL;
  269. m_pContext->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_pContext->Next (0, &pDummyObject))
  275. break;
  276. else
  277. pDummyObject->Release ();
  278. }
  279. return (i == m_pos);
  280. }