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.

319 lines
6.6 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // METHVAR.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines implementation of IEnumVARIANT for iterators of ISWbemMethodSet
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CMethodSetEnumVar::CMethodSetEnumVar
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CMethodSetEnumVar::CMethodSetEnumVar(CSWbemMethodSet *pMethodSet,
  23. ULONG initialPos)
  24. {
  25. m_cRef = 0;
  26. m_pos = 0;
  27. m_pMethodSet = pMethodSet;
  28. m_pMethodSet->AddRef ();
  29. InterlockedIncrement(&g_cObj);
  30. }
  31. //***************************************************************************
  32. //
  33. // CMethodSetEnumVar::~CMethodSetEnumVar
  34. //
  35. // DESCRIPTION:
  36. //
  37. // Destructor.
  38. //
  39. //***************************************************************************
  40. CMethodSetEnumVar::~CMethodSetEnumVar(void)
  41. {
  42. InterlockedDecrement(&g_cObj);
  43. if (m_pMethodSet)
  44. m_pMethodSet->Release ();
  45. }
  46. //***************************************************************************
  47. // HRESULT CMethodSetEnumVar::QueryInterface
  48. // long CMethodSetEnumVar::AddRef
  49. // long CMethodSetEnumVar::Release
  50. //
  51. // DESCRIPTION:
  52. //
  53. // Standard Com IUNKNOWN functions.
  54. //
  55. //***************************************************************************
  56. STDMETHODIMP CMethodSetEnumVar::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) CMethodSetEnumVar::AddRef(void)
  72. {
  73. InterlockedIncrement(&m_cRef);
  74. return m_cRef;
  75. }
  76. STDMETHODIMP_(ULONG) CMethodSetEnumVar::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 CMethodSetEnumVar::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 CMethodSetEnumVar::Reset ()
  103. {
  104. m_pos = 0;
  105. return S_OK;
  106. }
  107. //***************************************************************************
  108. //
  109. // SCODE CMethodSetEnumVar::Next
  110. //
  111. // DESCRIPTION:
  112. //
  113. // Get the next object in the enumeration
  114. //
  115. // PARAMETERS:
  116. //
  117. //
  118. // RETURN VALUES:
  119. //
  120. // S_OK success (all requested elements returned)
  121. // S_FALSE otherwise
  122. //
  123. //***************************************************************************
  124. HRESULT CMethodSetEnumVar::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_pMethodSet)
  139. {
  140. // Retrieve the next cElements elements.
  141. if (SeekCurrentPosition ())
  142. {
  143. for (l2 = 0; l2 < cElements; l2++)
  144. {
  145. HRESULT hRes2;
  146. ISWbemMethod *pMethod = NULL;
  147. if (SUCCEEDED(hRes2 = m_pMethodSet->Next (0, &pMethod)))
  148. {
  149. if (NULL == pMethod)
  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 = pMethod;
  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 CMethodSetEnumVar::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 CMethodSetEnumVar::Clone (
  191. IEnumVARIANT **ppEnum
  192. )
  193. {
  194. HRESULT hr = E_FAIL;
  195. if (NULL != ppEnum)
  196. {
  197. *ppEnum = NULL;
  198. if (m_pMethodSet)
  199. {
  200. CMethodSetEnumVar *pEnum = new CMethodSetEnumVar (m_pMethodSet, 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 CMethodSetEnumVar::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 CMethodSetEnumVar::Skip(
  228. ULONG cElements
  229. )
  230. {
  231. HRESULT hr = S_FALSE;
  232. long count = 0;
  233. m_pMethodSet->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 CMethodSetEnumVar::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 CMethodSetEnumVar::SeekCurrentPosition ()
  264. {
  265. ISWbemMethod *pDummyObject = NULL;
  266. m_pMethodSet->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_pMethodSet->Next (0, &pDummyObject))
  272. break;
  273. else
  274. pDummyObject->Release ();
  275. }
  276. return (i == m_pos);
  277. }