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.

253 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. Enum.hxx
  5. Abstract:
  6. Declaration of VSS_OBJECT_PROP_Array
  7. Adi Oltean [aoltean] 08/31/1999
  8. Revision History:
  9. Name Date Comments
  10. aoltean 08/31/1999 Created
  11. aoltean 09/09/1999 dss -> vss
  12. aoltean 09/13/1999 VSS_OBJECT_PROP_Copy moved into inc\Copy.hxx
  13. aoltean 09/20/1999 VSS_OBJECT_PROP_Copy renamed as VSS_OBJECT_PROP_Manager
  14. aoltean 09/21/1999 Renaming back VSS_OBJECT_PROP_Manager to VSS_OBJECT_PROP_Copy.
  15. Adding VSS_OBJECT_PROP_Ptr as a pointer to the properties structure.
  16. This pointer will serve as element in CSimpleArray constructs.
  17. Moving into basestor\vss\inc folder
  18. --*/
  19. #ifndef __VSS_ENUM_COORD_HXX__
  20. #define __VSS_ENUM_COORD_HXX__
  21. #if _MSC_VER > 1000
  22. #pragma once
  23. #endif
  24. ////////////////////////////////////////////////////////////////////////
  25. // Standard foo for file name aliasing. This code block must be after
  26. // all includes of VSS header files.
  27. //
  28. #ifdef VSS_FILE_ALIAS
  29. #undef VSS_FILE_ALIAS
  30. #endif
  31. #define VSS_FILE_ALIAS "INCENUMH"
  32. //
  33. ////////////////////////////////////////////////////////////////////////
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CVssGenericArray
  36. template < class Element, class Element_Ptr>
  37. class CVssGenericArray:
  38. public CSimpleArray <Element_Ptr>,
  39. public IUnknown
  40. {
  41. // Typedefs
  42. public:
  43. class iterator
  44. {
  45. public:
  46. iterator(): m_nIndex(0), m_pArr(NULL) {};
  47. iterator(CVssGenericArray* pArr, int nIndex = 0)
  48. : m_nIndex(nIndex), m_pArr(pArr)
  49. {
  50. BS_ASSERT(m_pArr->GetSize() >= m_nIndex); // Equality only when pointing to the "end"
  51. BS_ASSERT(m_pArr);
  52. };
  53. iterator(const iterator& it): // To support postfix ++
  54. m_nIndex(it.m_nIndex), m_pArr(it.m_pArr)
  55. {
  56. BS_ASSERT(m_pArr->GetSize() >= m_nIndex); // Equality only when pointing to the "end"
  57. BS_ASSERT(m_pArr);
  58. };
  59. iterator& operator = (const iterator& rhs) {
  60. m_nIndex = rhs.m_nIndex;
  61. m_pArr = rhs.m_pArr;
  62. BS_ASSERT(m_pArr);
  63. BS_ASSERT(m_pArr->GetSize() >= m_nIndex); // Equality only when pointing to the "end"
  64. return (*this);
  65. };
  66. bool operator != (const iterator& rhs) {
  67. BS_ASSERT(m_pArr);
  68. BS_ASSERT(m_pArr == rhs.m_pArr); // Impossible to be reached by the ATL code
  69. return (m_nIndex != rhs.m_nIndex);
  70. };
  71. Element& operator * () {
  72. BS_ASSERT(m_pArr);
  73. BS_ASSERT(m_nIndex <= m_pArr->GetSize());
  74. Element_Ptr& ptr = (*m_pArr)[m_nIndex];
  75. Element* pStruct = ptr.GetStruct();
  76. BS_ASSERT(pStruct);
  77. return *pStruct;
  78. };
  79. iterator operator ++ (int) { // Postfix ++
  80. BS_ASSERT(m_pArr);
  81. BS_ASSERT(m_nIndex < m_pArr->GetSize());
  82. m_nIndex++;
  83. return (*this);
  84. };
  85. private:
  86. int m_nIndex;
  87. CVssGenericArray* m_pArr;
  88. };
  89. // Constructors& destructors
  90. private:
  91. CVssGenericArray(const CVssGenericArray&);
  92. public:
  93. CVssGenericArray(): m_lRef(0) {};
  94. // Operations
  95. public:
  96. iterator begin() {
  97. return iterator(this, 0);
  98. }
  99. iterator end() {
  100. return iterator(this, GetSize());
  101. }
  102. // Ovverides
  103. public:
  104. STDMETHOD(QueryInterface)(REFIID iid, void** pp)
  105. {
  106. if (pp == NULL)
  107. return E_INVALIDARG;
  108. if (iid != IID_IUnknown)
  109. return E_NOINTERFACE;
  110. AddRef();
  111. IUnknown** pUnk = reinterpret_cast<IUnknown**>(pp);
  112. (*pUnk) = static_cast<IUnknown*>(this);
  113. return S_OK;
  114. };
  115. STDMETHOD_(ULONG, AddRef)()
  116. {
  117. return ::InterlockedIncrement(&m_lRef);
  118. };
  119. STDMETHOD_(ULONG, Release)()
  120. {
  121. LONG l = ::InterlockedDecrement(&m_lRef);
  122. if (l == 0)
  123. delete this; // We suppose that we always allocate this object on the heap!
  124. return l;
  125. };
  126. // Implementation
  127. public:
  128. LONG m_lRef;
  129. };
  130. /////////////////////////////////////////////////////////////////////////////
  131. // Template instantiations
  132. class VSS_OBJECT_PROP_Array: public CVssGenericArray<VSS_OBJECT_PROP, VSS_OBJECT_PROP_Ptr> {};
  133. class VSS_MGMT_OBJECT_PROP_Array: public CVssGenericArray<VSS_MGMT_OBJECT_PROP, VSS_MGMT_OBJECT_PROP_Ptr> {};
  134. class CVssEnumFromArray:
  135. public CComEnumOnSTL<
  136. IVssEnumObject, &IID_IVssEnumObject,
  137. VSS_OBJECT_PROP, VSS_OBJECT_PROP_Copy, VSS_OBJECT_PROP_Array > {};
  138. class CVssMgmtEnumFromArray:
  139. public CComEnumOnSTL<
  140. IVssEnumMgmtObject, &IID_IVssEnumMgmtObject,
  141. VSS_MGMT_OBJECT_PROP, VSS_MGMT_OBJECT_PROP_Copy, VSS_MGMT_OBJECT_PROP_Array > {};
  142. /////////////////////////////////////////////////////////////////////////////
  143. // Utility functions
  144. /*++
  145. Pattern for a Query function:
  146. --*/
  147. template <
  148. class CVssGenericEnumFromArray, // Enum itf implementation (for ex. CVssMgmtEnumFromArray)
  149. class IEnumInterface, // Type of the enum interface (for ex. IVssEnumMgmtObject)
  150. class ElementArray // Wrapper around the structures array (for ex. VSS_MGMT_OBJECT_PROP_Ptr)
  151. >
  152. HRESULT inline VssBuildEnumInterface(
  153. IN CVssDebugInfo dbgInfo, // Caller debugging info
  154. IN ElementArray* pArray, // wrapper around the array of strutures
  155. OUT IEnumInterface **ppEnum // Returned enumerator interface
  156. )
  157. {
  158. CVssFunctionTracer ft(VSSDBG_GEN, L"VssBuildEnumInterface");
  159. // Parameter check
  160. BS_ASSERT(pArray);
  161. BS_ASSERT(ppEnum);
  162. BS_ASSERT(*ppEnum == NULL);
  163. // Create the enumerator object. Beware that its reference count will be zero.
  164. CComObject<CVssGenericEnumFromArray>* pEnumObject = NULL;
  165. ft.hr = CComObject<CVssGenericEnumFromArray>::CreateInstance(&pEnumObject);
  166. if (ft.HrFailed())
  167. ft.Throw( dbgInfo, E_OUTOFMEMORY,
  168. L"Cannot create enumerator instance. [0x%08lx]", ft.hr);
  169. BS_ASSERT(pEnumObject);
  170. // Get the pointer to the IVssEnumObject interface.
  171. // Now pEnumObject's reference count becomes 1 (because of the smart pointer).
  172. // So if a throw occurs the enumerator object will be safely destroyed by the smart ptr.
  173. CComPtr<IUnknown> pUnknown = pEnumObject->GetUnknown();
  174. BS_ASSERT(pUnknown);
  175. // Initialize the enumerator object.
  176. // The array's reference count becomes now 2, because IEnumOnSTLImpl::m_spUnk is also a smart ptr.
  177. BS_ASSERT(pArray);
  178. ft.hr = pEnumObject->Init(static_cast<IUnknown*>(pArray), *pArray);
  179. if (ft.HrFailed()) {
  180. BS_ASSERT(false); // dev error
  181. ft.Throw( dbgInfo, E_UNEXPECTED,
  182. L"Cannot initialize enumerator instance. [0x%08lx]", ft.hr);
  183. }
  184. // Initialize the enumerator object.
  185. // The enumerator reference count becomes now 2.
  186. ft.hr = pUnknown->QueryInterface(__uuidof(IEnumInterface), (void**)ppEnum);
  187. if ( ft.HrFailed() ) {
  188. BS_ASSERT(false); // dev error
  189. ft.Throw( dbgInfo, E_UNEXPECTED,
  190. L"Error querying the <IEnumInterface> interface with GUID "
  191. WSTR_GUID_FMT L". hr = 0x%08lx",
  192. GUID_PRINTF_ARG(__uuidof(IEnumInterface)), ft.hr);
  193. }
  194. BS_ASSERT(*ppEnum);
  195. BS_ASSERT( !ft.HrFailed() );
  196. return (pArray->GetSize() != 0)? S_OK: S_FALSE;
  197. }
  198. #endif // __VSS_ENUM_COORD_HXX__