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.

209 lines
5.2 KiB

  1. /*****************************************************************************\
  2. FILE: EnumUnknown.cpp
  3. DESCRIPTION:
  4. This code will implement IEnumUnknown for an HDPA.
  5. BryanSt 5/30/2000 Updated and Converted to C++
  6. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  7. \*****************************************************************************/
  8. #include "priv.h"
  9. #include "EnumUnknown.h"
  10. class CEnumUnknown : public IEnumUnknown
  11. {
  12. public:
  13. //////////////////////////////////////////////////////
  14. // Public Interfaces
  15. //////////////////////////////////////////////////////
  16. // *** IUnknown ***
  17. virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  18. virtual STDMETHODIMP_(ULONG) AddRef(void);
  19. virtual STDMETHODIMP_(ULONG) Release(void);
  20. // *** IEnumUnknown ***
  21. virtual STDMETHODIMP Next(IN ULONG celt, IN IUnknown ** rgelt, IN ULONG * pceltFetched);
  22. virtual STDMETHODIMP Skip(IN ULONG celt);
  23. virtual STDMETHODIMP Reset(void);
  24. virtual STDMETHODIMP Clone(OUT IEnumUnknown ** ppenum);
  25. protected:
  26. HRESULT _Initialize(void);
  27. private:
  28. CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex);
  29. virtual ~CEnumUnknown(void);
  30. // Private Member Variables
  31. long m_cRef;
  32. IUnknown * m_punkOwner; // The owner of m_pUnknownArray. We hold a ref on this guy to keep m_pUnknownArray valid.
  33. IUnknown ** m_pUnknownArray; // The array of IUnknowns
  34. int m_nArraySize; // The size of m_pUnknownArray
  35. int m_nIndex; // The current index during enum.
  36. // Private Member Functions
  37. // Friend Functions
  38. friend HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown);
  39. };
  40. //===========================
  41. // *** Class Internals & Helpers ***
  42. //===========================
  43. //===========================
  44. // *** IEnumUnknown Interface ***
  45. //===========================
  46. HRESULT CEnumUnknown::Next(IN ULONG celt, IN IUnknown ** rgelt, IN ULONG * pceltFetched)
  47. {
  48. HRESULT hr = E_INVALIDARG;
  49. if (rgelt && pceltFetched)
  50. {
  51. ULONG nIndex;
  52. hr = S_OK;
  53. *pceltFetched = 0;
  54. for (nIndex = 0; nIndex < celt; nIndex++,m_nIndex++)
  55. {
  56. if ((m_nIndex < m_nArraySize) && m_pUnknownArray[m_nIndex])
  57. {
  58. rgelt[nIndex] = NULL;
  59. IUnknown_Set(&(rgelt[nIndex]), m_pUnknownArray[m_nIndex]);
  60. (*pceltFetched)++;
  61. }
  62. else
  63. {
  64. rgelt[nIndex] = NULL;
  65. }
  66. }
  67. }
  68. return hr;
  69. }
  70. HRESULT CEnumUnknown::Skip(IN ULONG celt)
  71. {
  72. m_nIndex += celt;
  73. return S_OK;
  74. }
  75. HRESULT CEnumUnknown::Reset(void)
  76. {
  77. m_nIndex = 0;
  78. return S_OK;
  79. }
  80. HRESULT CEnumUnknown::Clone(OUT IEnumUnknown ** ppenum)
  81. {
  82. HRESULT hr = E_INVALIDARG;
  83. if (ppenum)
  84. {
  85. hr = CEnumUnknown_CreateInstance(SAFECAST(this, IEnumUnknown *), m_pUnknownArray, m_nArraySize, m_nIndex, ppenum);
  86. }
  87. return hr;
  88. }
  89. //===========================
  90. // *** IUnknown Interface ***
  91. //===========================
  92. ULONG CEnumUnknown::AddRef()
  93. {
  94. return InterlockedIncrement(&m_cRef);
  95. }
  96. ULONG CEnumUnknown::Release()
  97. {
  98. ASSERT( 0 != m_cRef );
  99. ULONG cRef = InterlockedDecrement(&m_cRef);
  100. if ( 0 == cRef )
  101. {
  102. delete this;
  103. }
  104. return cRef;
  105. }
  106. HRESULT CEnumUnknown::QueryInterface(REFIID riid, void **ppvObj)
  107. {
  108. static const QITAB qit[] = {
  109. QITABENT(CEnumUnknown, IEnumUnknown),
  110. { 0 },
  111. };
  112. return QISearch(this, qit, riid, ppvObj);
  113. }
  114. //===========================
  115. // *** Class Methods ***
  116. //===========================
  117. CEnumUnknown::CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex) : m_cRef(1)
  118. {
  119. DllAddRef();
  120. // This needs to be allocated in Zero Inited Memory.
  121. // Assert that all Member Variables are inited to Zero.
  122. ASSERT(!m_punkOwner);
  123. IUnknown_Set(&m_punkOwner, punkOwner);
  124. m_pUnknownArray = ppArray;
  125. m_nArraySize = nArraySize;
  126. m_nIndex = nIndex;
  127. }
  128. CEnumUnknown::~CEnumUnknown()
  129. {
  130. IUnknown_Set(&m_punkOwner, NULL);
  131. DllRelease();
  132. }
  133. HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown)
  134. {
  135. HRESULT hr = E_INVALIDARG;
  136. if (punkOwner && ppArray && ppEnumUnknown)
  137. {
  138. CEnumUnknown * pObject = new CEnumUnknown(punkOwner, ppArray, nArraySize, nIndex);
  139. *ppEnumUnknown = NULL;
  140. if (pObject)
  141. {
  142. hr = pObject->QueryInterface(IID_PPV_ARG(IEnumUnknown, ppEnumUnknown));
  143. pObject->Release();
  144. }
  145. else
  146. {
  147. hr = E_OUTOFMEMORY;
  148. }
  149. }
  150. return hr;
  151. }