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.

207 lines
4.9 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. if (InterlockedDecrement(&m_cRef))
  99. return m_cRef;
  100. delete this;
  101. return 0;
  102. }
  103. HRESULT CEnumUnknown::QueryInterface(REFIID riid, void **ppvObj)
  104. {
  105. static const QITAB qit[] = {
  106. QITABENT(CEnumUnknown, IEnumUnknown),
  107. { 0 },
  108. };
  109. return QISearch(this, qit, riid, ppvObj);
  110. }
  111. //===========================
  112. // *** Class Methods ***
  113. //===========================
  114. CEnumUnknown::CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex) : m_cRef(1)
  115. {
  116. DllAddRef();
  117. // This needs to be allocated in Zero Inited Memory.
  118. // Assert that all Member Variables are inited to Zero.
  119. ASSERT(!m_punkOwner);
  120. IUnknown_Set(&m_punkOwner, punkOwner);
  121. m_pUnknownArray = ppArray;
  122. m_nArraySize = nArraySize;
  123. m_nIndex = nIndex;
  124. }
  125. CEnumUnknown::~CEnumUnknown()
  126. {
  127. IUnknown_Set(&m_punkOwner, NULL);
  128. DllRelease();
  129. }
  130. HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown)
  131. {
  132. HRESULT hr = E_INVALIDARG;
  133. if (punkOwner && ppArray && ppEnumUnknown)
  134. {
  135. CEnumUnknown * pObject = new CEnumUnknown(punkOwner, ppArray, nArraySize, nIndex);
  136. *ppEnumUnknown = NULL;
  137. if (pObject)
  138. {
  139. hr = pObject->QueryInterface(IID_PPV_ARG(IEnumUnknown, ppEnumUnknown));
  140. pObject->Release();
  141. }
  142. else
  143. {
  144. hr = E_OUTOFMEMORY;
  145. }
  146. }
  147. return hr;
  148. }