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.

251 lines
5.2 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. pointerq.cxx
  5. Abstract :
  6. This file contains the routines for the pointer queues
  7. Author :
  8. Mike Zoran mzoran Jun 2000.
  9. Revision History :
  10. ---------------------------------------------------------------------*/
  11. #include "ndrp.h"
  12. #include "hndl.h"
  13. #include "ndrole.h"
  14. #include "attack.h"
  15. #include "pointerq.h"
  16. void
  17. NDR32_POINTER_QUEUE_STATE::Free(
  18. NDR_POINTER_QUEUE_ELEMENT *pElement
  19. )
  20. {
  21. #if defined(DBG)
  22. memset( pElement, 0xBD, NdrMaxPointerQueueElement);
  23. #endif
  24. pElement->pNext = pFreeList;
  25. pFreeList = pElement;
  26. }
  27. NDR_POINTER_QUEUE_ELEMENT *
  28. NDR32_POINTER_QUEUE_STATE::Allocate()
  29. {
  30. NDR_POINTER_QUEUE_ELEMENT *pNewElement;
  31. if ( pFreeList )
  32. {
  33. pNewElement = pFreeList;
  34. pFreeList = pNewElement->pNext;
  35. }
  36. else
  37. {
  38. pNewElement = InternalAllocate();
  39. }
  40. #if defined(DBG)
  41. memset( pNewElement, 0xDB, NdrMaxPointerQueueElement );
  42. #endif
  43. return pNewElement;
  44. }
  45. void
  46. NDR32_POINTER_QUEUE_STATE::FreeAll()
  47. {
  48. while ( pAllocationList )
  49. {
  50. AllocationElement *pThisAlloc = pAllocationList;
  51. pAllocationList = pAllocationList->pNext;
  52. I_RpcFree( pThisAlloc );
  53. }
  54. }
  55. NDR_POINTER_QUEUE_ELEMENT *
  56. NDR32_POINTER_QUEUE_STATE::InternalAllocate()
  57. {
  58. if ( !pAllocationList ||
  59. (ItemsToAllocate == pAllocationList->ItemsAllocated ) )
  60. {
  61. struct AllocationElement *pElement =
  62. (struct AllocationElement *)I_RpcAllocate( sizeof(AllocationElement) );
  63. if ( !pElement )
  64. {
  65. RpcRaiseException( RPC_S_OUT_OF_MEMORY );
  66. }
  67. pElement->pNext = pAllocationList;
  68. pElement->ItemsAllocated = 0;
  69. pAllocationList = pElement;
  70. }
  71. return (NDR_POINTER_QUEUE_ELEMENT*)
  72. (NDR_POINTER_QUEUE_ELEMENT*)pAllocationList->Data[pAllocationList->ItemsAllocated++];
  73. }
  74. #if defined(BUILD_NDR64)
  75. NDR_POINTER_QUEUE_ELEMENT *
  76. NDR64_POINTER_QUEUE_STATE::Allocate()
  77. {
  78. NDR_POINTER_QUEUE_ELEMENT *pNewElement;
  79. if ( pProcContext->pQueueFreeList )
  80. {
  81. pNewElement = pProcContext->pQueueFreeList;
  82. pProcContext->pQueueFreeList = pNewElement->pNext;
  83. }
  84. else
  85. {
  86. pNewElement = (NDR_POINTER_QUEUE_ELEMENT *)
  87. NdrpAlloca( &pProcContext->AllocateContext,
  88. NdrMaxPointerQueueElement );
  89. }
  90. #if defined(DBG)
  91. memset( pNewElement, 0xDB, NdrMaxPointerQueueElement );
  92. #endif
  93. return pNewElement;
  94. }
  95. void
  96. NDR64_POINTER_QUEUE_STATE::Free(
  97. NDR_POINTER_QUEUE_ELEMENT *pElement
  98. )
  99. {
  100. #if defined(DBG)
  101. memset( pElement, 0xBD, NdrMaxPointerQueueElement);
  102. #endif
  103. pElement->pNext = pProcContext->pQueueFreeList;
  104. pProcContext->pQueueFreeList = pElement;
  105. }
  106. #endif
  107. inline NDR_POINTER_QUEUE::STORAGE::STORAGE( ) :
  108. pHead(NULL),
  109. pPrevHead(NULL),
  110. pPrevInsertPointer(NULL),
  111. pInsertPointer(&pHead)
  112. {
  113. }
  114. inline void NDR_POINTER_QUEUE::STORAGE::MergeContext()
  115. {
  116. // Add old list to end of this list.
  117. if ( pPrevHead )
  118. {
  119. // Append list
  120. *pInsertPointer = pPrevHead;
  121. // Set insert pointer to end of old list
  122. pInsertPointer = pPrevInsertPointer;
  123. }
  124. pPrevHead = NULL;
  125. pPrevInsertPointer = NULL;
  126. }
  127. inline void NDR_POINTER_QUEUE::STORAGE::NewContext()
  128. {
  129. pPrevHead = pHead;
  130. pPrevInsertPointer = pInsertPointer;
  131. pHead = NULL;
  132. pInsertPointer = &pHead;
  133. }
  134. inline void NDR_POINTER_QUEUE::STORAGE::InsertTail( NDR_POINTER_QUEUE_ELEMENT *pNewNode )
  135. {
  136. *pInsertPointer = pNewNode;
  137. pNewNode->pNext = NULL;
  138. pInsertPointer = &pNewNode->pNext;
  139. }
  140. inline NDR_POINTER_QUEUE_ELEMENT *NDR_POINTER_QUEUE::STORAGE::RemoveHead()
  141. {
  142. NDR_POINTER_QUEUE_ELEMENT *pOldHead = pHead;
  143. if (!pHead)
  144. {
  145. return pHead;
  146. }
  147. if ( !pHead->pNext )
  148. {
  149. // Last item, reinitialize list.
  150. pHead = NULL;
  151. pInsertPointer = &pHead->pNext;
  152. }
  153. else
  154. {
  155. pHead = pHead->pNext;
  156. }
  157. return pOldHead;
  158. }
  159. #if defined(DBG)
  160. ulong NdrPointerQueueLogLevel;
  161. #endif
  162. void NDR_POINTER_QUEUE::Enque( NDR_POINTER_QUEUE_ELEMENT * pElement )
  163. {
  164. Storage.InsertTail( pElement );
  165. #if defined(DBG)
  166. if ( NdrPointerQueueLogLevel )
  167. {
  168. DbgPrint( "Queing Element %p\n", pElement );
  169. pElement->Print();
  170. }
  171. #endif
  172. }
  173. void NDR_POINTER_QUEUE::Dispatch()
  174. {
  175. while ( 1 )
  176. {
  177. NDR_POINTER_QUEUE_ELEMENT *pHead = Storage.RemoveHead();
  178. if ( !pHead )
  179. return;
  180. #if defined(DBG)
  181. if ( NdrPointerQueueLogLevel )
  182. {
  183. DbgPrint( "Dispatching Element: %p\n", pHead );
  184. pHead->Print();
  185. }
  186. #endif
  187. Storage.NewContext();
  188. pHead->Dispatch( pStubMsg );
  189. pQueueState->Free( pHead );
  190. Storage.MergeContext();
  191. }
  192. }
  193. NDR_POINTER_QUEUE::NDR_POINTER_QUEUE( PMIDL_STUB_MESSAGE pNewStubMsg,
  194. NDR_POINTER_QUEUE_STATE *pNewState ) :
  195. pStubMsg( pNewStubMsg ),
  196. Storage(),
  197. pQueueState(pNewState)
  198. {
  199. }