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.

269 lines
4.9 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. cenum.cpp
  5. Abstract :
  6. CPP files to enumeration abstraction.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #include "stdafx.h"
  11. #if !defined( BITS_V12_ON_NT4 )
  12. #include "cenum.tmh"
  13. #endif
  14. #define MAGIC_ACTIVE 0x44446666
  15. #define MAGIC_INACTIVE 0x55553333
  16. template<class B, class T, class P>
  17. CEnum<B,T,P>::CEnum() :
  18. m_CurrentIndex(0),
  19. m_magic( MAGIC_ACTIVE )
  20. {
  21. memset( m_stack, 0, sizeof(m_stack) );
  22. }
  23. template<class B, class T, class P>
  24. HRESULT
  25. CEnum<B,T,P>::NextInternal(
  26. ULONG celt,
  27. T rgelt[],
  28. ULONG * pceltFetched
  29. )
  30. {
  31. CheckMagicValue();
  32. ULONG i;
  33. HRESULT Hr = S_OK;
  34. CAutoExclusiveLock LockHolder(m_mutex);
  35. LogPublicApiBegin( "celt %u, rgelt %p, pceltFetched %p", celt, rgelt, pceltFetched );
  36. ULONG Fetched = 0;
  37. try
  38. {
  39. for (unsigned int c=0; c<celt; c++)
  40. m_ItemPolicy.Init( rgelt[c] );
  41. if ( !pceltFetched && (1 != celt) )
  42. {
  43. LogWarning("Return count pointer is NULL, but requested count isn't 1" );
  44. throw ComError( E_INVALIDARG );
  45. }
  46. for (i=0; ( i < celt ) && ( m_CurrentIndex < m_items.size() ); i++, m_CurrentIndex++)
  47. {
  48. m_ItemPolicy.Copy( rgelt[i], m_items[m_CurrentIndex] );
  49. Fetched++;
  50. }
  51. if ( pceltFetched )
  52. {
  53. *pceltFetched = Fetched;
  54. }
  55. if ( Fetched != celt )
  56. {
  57. Hr = S_FALSE;
  58. }
  59. }
  60. catch ( ComError exception )
  61. {
  62. Hr = exception.Error();
  63. }
  64. LogPublicApiEnd( "celt %u, rgelt %p, pceltFetched %p(%u)", celt, rgelt, pceltFetched, pceltFetched ? *pceltFetched : 1 );
  65. return Hr;
  66. }
  67. template<class B, class T, class P>
  68. HRESULT
  69. CEnum<B,T,P>::CloneInternal(
  70. B **ppEnum
  71. )
  72. {
  73. CheckMagicValue();
  74. HRESULT Hr = S_OK;
  75. CEnum<B,T,P> * pEnum = NULL;
  76. CAutoExclusiveLock LockHolder( m_mutex );
  77. LogPublicApiBegin( "ppEnum %p", ppEnum );
  78. try
  79. {
  80. pEnum = new CEnum<B,T,P>;
  81. for (CItemList::iterator iter = m_items.begin(); iter != m_items.end(); ++iter)
  82. {
  83. pEnum->Add( *iter );
  84. }
  85. pEnum->m_CurrentIndex = m_CurrentIndex;
  86. }
  87. catch ( ComError exception )
  88. {
  89. delete pEnum;
  90. pEnum = NULL;
  91. Hr = exception.Error();
  92. }
  93. *ppEnum = pEnum;
  94. LogPublicApiEnd( "ppEnum %p(%p)", ppEnum, *ppEnum );
  95. return Hr;
  96. }
  97. template<class B, class T, class P>
  98. void
  99. CEnum<B, T,P>::Add(
  100. T item
  101. )
  102. {
  103. CheckMagicValue();
  104. CAutoExclusiveLock LockHolder( m_mutex );
  105. T MyItem;
  106. try
  107. {
  108. m_ItemPolicy.Copy( MyItem, item );
  109. m_items.push_back( MyItem );
  110. }
  111. catch( ComError Error )
  112. {
  113. m_ItemPolicy.Destroy( MyItem );
  114. throw;
  115. }
  116. }
  117. template<class B, class T, class P>
  118. HRESULT
  119. CEnum<B,T,P>::GetCountInternal(
  120. ULONG * pCount
  121. )
  122. {
  123. CheckMagicValue();
  124. HRESULT Hr = S_OK;
  125. CAutoSharedLock LockHolder( m_mutex );
  126. LogPublicApiBegin( "pCount %p", pCount );
  127. *pCount = m_items.size();
  128. LogPublicApiEnd( "pCount %p(%u)", pCount, *pCount );
  129. return Hr;
  130. }
  131. template<class B, class T, class P>
  132. HRESULT
  133. CEnum<B, T, P>::ResetInternal()
  134. {
  135. CheckMagicValue();
  136. HRESULT Hr = S_OK;
  137. CAutoExclusiveLock LockHolder( m_mutex );
  138. LogPublicApiBegin( " " );
  139. m_CurrentIndex = 0;
  140. LogPublicApiEnd( " " );
  141. return Hr;
  142. }
  143. template<class B, class T, class P>
  144. HRESULT
  145. CEnum<B, T, P>::SkipInternal(
  146. ULONG celt
  147. )
  148. {
  149. CheckMagicValue();
  150. HRESULT Hr = S_OK;
  151. CAutoExclusiveLock LockHolder( m_mutex );
  152. LogPublicApiBegin( "celt %u", celt );
  153. while(celt)
  154. {
  155. if ( m_CurrentIndex >= m_items.size() )
  156. break; // Hit the end of the list
  157. m_CurrentIndex++;
  158. --celt;
  159. }
  160. if (celt)
  161. {
  162. LogWarning( "Attempt to skip too many elements." );
  163. Hr = S_FALSE;
  164. }
  165. LogPublicApiEnd( "celt %u", celt );
  166. return Hr;
  167. }
  168. template<class B, class T, class P>
  169. CEnum<B,T,P>::~CEnum()
  170. {
  171. CheckMagicValue();
  172. m_magic = MAGIC_INACTIVE;
  173. for (CItemList::const_iterator iter = m_items.begin(); iter != m_items.end(); ++iter)
  174. {
  175. T Item = (*iter);
  176. m_ItemPolicy.Destroy( Item );
  177. }
  178. }
  179. template<class B, class T, class P>
  180. void CEnum<B,T,P>::CheckMagicValue()
  181. {
  182. ASSERT( m_magic == MAGIC_ACTIVE );
  183. }
  184. CEnumJobs::CEnumJobs() :
  185. CEnumInterface<IEnumBackgroundCopyJobs,IBackgroundCopyJob>()
  186. {}
  187. CEnumFiles::CEnumFiles() :
  188. CEnumInterface<IEnumBackgroundCopyFiles,IBackgroundCopyFile>()
  189. {}
  190. CEnumOldGroups::CEnumOldGroups() :
  191. CEnumItem<IEnumBackgroundCopyGroups,GUID>( )
  192. {}
  193. CEnumOldJobs::CEnumOldJobs() :
  194. CEnumItem<IEnumBackgroundCopyJobs1,GUID>( )
  195. {}