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.

378 lines
7.2 KiB

  1. #ifndef __STACK_CPP
  2. #define __STACK_CPP
  3. /*
  4. * Class:
  5. *
  6. * WmiAllocator
  7. *
  8. * Description:
  9. *
  10. * Provides abstraction above heap allocation functions
  11. *
  12. * Version:
  13. *
  14. * Initial
  15. *
  16. * Last Changed:
  17. *
  18. * See Source Depot for change history
  19. *
  20. */
  21. #if 0
  22. #include <precomp.h>
  23. #include <windows.h>
  24. #include <stdio.h>
  25. #include <Allocator.h>
  26. #include <Stack.h>
  27. #endif
  28. /******************************************************************************
  29. *
  30. * Name:
  31. *
  32. *
  33. * Description:
  34. *
  35. *
  36. *****************************************************************************/
  37. template <class WmiElement, ULONG ElementSize>
  38. WmiStack <WmiElement,ElementSize > :: WmiStack <WmiElement,ElementSize > (
  39. WmiAllocator &a_Allocator
  40. ) : m_Allocator ( a_Allocator ) ,
  41. m_Size ( 0xFFFFFFFF ) ,
  42. m_AllocatedSize ( 0 ) ,
  43. m_Top ( NULL )
  44. {
  45. }
  46. /******************************************************************************
  47. *
  48. * Name:
  49. *
  50. *
  51. * Description:
  52. *
  53. *
  54. *****************************************************************************/
  55. template <class WmiElement, ULONG ElementSize>
  56. WmiStack <WmiElement,ElementSize > :: ~WmiStack <WmiElement,ElementSize > ()
  57. {
  58. WmiStatusCode t_StatusCode = UnInitialize () ;
  59. }
  60. /******************************************************************************
  61. *
  62. * Name:
  63. *
  64. *
  65. * Description:
  66. *
  67. *
  68. *****************************************************************************/
  69. template <class WmiElement, ULONG ElementSize>
  70. WmiStatusCode WmiStack <WmiElement,ElementSize > :: Initialize ()
  71. {
  72. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  73. if ( ElementSize < 31 )
  74. {
  75. t_StatusCode = Grow_ElementDir () ;
  76. }
  77. else
  78. {
  79. t_StatusCode = e_StatusCode_InvalidArgs ;
  80. }
  81. return t_StatusCode ;
  82. }
  83. /******************************************************************************
  84. *
  85. * Name:
  86. *
  87. *
  88. * Description:
  89. *
  90. *
  91. *****************************************************************************/
  92. template <class WmiElement, ULONG ElementSize>
  93. WmiStatusCode WmiStack <WmiElement,ElementSize > :: UnInitialize ()
  94. {
  95. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  96. if ( m_AllocatedSize )
  97. {
  98. t_StatusCode = UnInitialize_ElementDir ( m_AllocatedSize ) ;
  99. m_Size = 0 ;
  100. m_AllocatedSize = 0 ;
  101. }
  102. return t_StatusCode ;
  103. }
  104. /******************************************************************************
  105. *
  106. * Name:
  107. *
  108. *
  109. * Description:
  110. *
  111. *
  112. *****************************************************************************/
  113. template <class WmiElement, ULONG ElementSize>
  114. WmiStatusCode WmiStack <WmiElement,ElementSize > :: Top ( WmiElement &a_Element )
  115. {
  116. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  117. if ( m_Size != 0xFFFFFFFF )
  118. {
  119. ULONG t_Index = ( m_Size ) & ( STACK_ELEMENT_DIR_MASK ) ;
  120. try
  121. {
  122. a_Element = m_Top->m_Block [ t_Index ] ;
  123. }
  124. catch ( Wmi_Heap_Exception &a_Exception )
  125. {
  126. return e_StatusCode_OutOfMemory ;
  127. }
  128. catch ( ... )
  129. {
  130. return e_StatusCode_Unknown ;
  131. }
  132. }
  133. else
  134. {
  135. t_StatusCode = e_StatusCode_NotInitialized ;
  136. }
  137. return t_StatusCode ;
  138. }
  139. /******************************************************************************
  140. *
  141. * Name:
  142. *
  143. *
  144. * Description:
  145. *
  146. *
  147. *****************************************************************************/
  148. template <class WmiElement, ULONG ElementSize>
  149. WmiStatusCode WmiStack <WmiElement,ElementSize > :: Push (
  150. const WmiElement &a_Element
  151. )
  152. {
  153. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  154. if ( ! m_AllocatedSize )
  155. {
  156. t_StatusCode = Initialize () ;
  157. }
  158. if ( t_StatusCode == e_StatusCode_Success )
  159. {
  160. m_Size ++ ;
  161. if ( m_Size == m_AllocatedSize )
  162. {
  163. t_StatusCode = Grow_ElementDir () ;
  164. }
  165. if ( t_StatusCode == e_StatusCode_Success )
  166. {
  167. ULONG t_Index = ( m_Size ) & ( STACK_ELEMENT_DIR_MASK ) ;
  168. try
  169. {
  170. m_Top->m_Block [ t_Index ] = a_Element ;
  171. }
  172. catch ( Wmi_Heap_Exception &a_Exception )
  173. {
  174. m_Size -- ;
  175. return e_StatusCode_OutOfMemory ;
  176. }
  177. catch ( ... )
  178. {
  179. m_Size -- ;
  180. return e_StatusCode_Unknown ;
  181. }
  182. }
  183. else
  184. {
  185. m_Size -- ;
  186. }
  187. }
  188. return t_StatusCode ;
  189. }
  190. /******************************************************************************
  191. *
  192. * Name:
  193. *
  194. *
  195. * Description:
  196. *
  197. *
  198. *****************************************************************************/
  199. template <class WmiElement, ULONG ElementSize>
  200. WmiStatusCode WmiStack <WmiElement,ElementSize > :: Pop ()
  201. {
  202. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  203. if ( m_Size != 0xFFFFFFFF )
  204. {
  205. if ( ( ( m_Size ) & ( STACK_ELEMENT_DIR_MASK ) ) == 0 )
  206. {
  207. t_StatusCode = Shrink_ElementDir () ;
  208. }
  209. m_Size -- ;
  210. }
  211. else
  212. {
  213. t_StatusCode = e_StatusCode_NotInitialized ;
  214. }
  215. return t_StatusCode ;
  216. }
  217. /******************************************************************************
  218. *
  219. * Name:
  220. *
  221. *
  222. * Description:
  223. *
  224. *
  225. *****************************************************************************/
  226. template <class WmiElement, ULONG ElementSize>
  227. WmiStatusCode WmiStack <WmiElement,ElementSize > :: UnInitialize_ElementDir (
  228. ULONG a_Size
  229. )
  230. {
  231. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  232. bool t_RoundUp = ( a_Size & STACK_ELEMENT_DIR_MASK ) != 0 ;
  233. ULONG t_Size = ( a_Size >> STACK_ELEMENT_DIR_BIT_SIZE ) + ( t_RoundUp ? 1 : 0 ) ;
  234. WmiElementDir *t_Previous = NULL ;
  235. for ( ULONG t_Index = 0 ; t_Index < t_Size ; t_Index ++ )
  236. {
  237. if ( m_Top )
  238. {
  239. t_Previous = m_Top->m_Previous ;
  240. t_StatusCode = m_Allocator.Delete (
  241. ( void * ) m_Top
  242. ) ;
  243. m_Top = t_Previous ;
  244. }
  245. else
  246. {
  247. break ;
  248. }
  249. }
  250. m_AllocatedSize = 0 ;
  251. return t_StatusCode ;
  252. }
  253. /******************************************************************************
  254. *
  255. * Name:
  256. *
  257. *
  258. * Description:
  259. *
  260. *
  261. *****************************************************************************/
  262. template <class WmiElement, ULONG ElementSize>
  263. WmiStatusCode WmiStack <WmiElement,ElementSize > :: Grow_ElementDir ()
  264. {
  265. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  266. WmiElementDir *t_Top = NULL ;
  267. t_StatusCode = m_Allocator.New (
  268. ( void ** ) & t_Top ,
  269. sizeof ( WmiElementDir )
  270. ) ;
  271. if ( t_StatusCode == e_StatusCode_Success )
  272. {
  273. :: new ( ( void * ) t_Top ) WmiElementDir ;
  274. t_Top->m_Previous = m_Top ;
  275. m_Top = t_Top ;
  276. m_AllocatedSize = m_AllocatedSize + ( STACK_ELEMENT_DIR_SIZE ) ;
  277. }
  278. return t_StatusCode ;
  279. }
  280. /******************************************************************************
  281. *
  282. * Name:
  283. *
  284. *
  285. * Description:
  286. *
  287. *
  288. *****************************************************************************/
  289. template <class WmiElement, ULONG ElementSize>
  290. WmiStatusCode WmiStack <WmiElement,ElementSize > :: Shrink_ElementDir ()
  291. {
  292. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  293. if ( m_Top )
  294. {
  295. WmiElementDir *t_Previous = m_Top->m_Previous ;
  296. m_Top->~WmiElementDir () ;
  297. t_StatusCode = m_Allocator.Delete (
  298. ( void * ) m_Top
  299. ) ;
  300. m_Top = t_Previous ;
  301. m_AllocatedSize = m_AllocatedSize - ( STACK_ELEMENT_DIR_SIZE ) ;
  302. }
  303. return t_StatusCode ;
  304. }
  305. #endif __STACK_CPP