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.

819 lines
23 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. pointerq.h
  5. Abstract :
  6. This file contains the routines for pointer queues.
  7. Author :
  8. Mike Zoran mzoran Jun 2000.
  9. Revision History :
  10. ---------------------------------------------------------------------*/
  11. #include "ndrp.h"
  12. #if !defined(__POINTERQ_H__)
  13. #define __POINTERQ_H__
  14. template<class T>
  15. class SAVE_CONTEXT
  16. {
  17. const T OldValue;
  18. T & LocationToRestore;
  19. public:
  20. __forceinline SAVE_CONTEXT(T & Location) :
  21. OldValue( Location ),
  22. LocationToRestore( Location )
  23. {}
  24. __forceinline SAVE_CONTEXT(T & Location, T NewValue) :
  25. OldValue( Location ),
  26. LocationToRestore( Location )
  27. {
  28. Location = NewValue;
  29. }
  30. __forceinline ~SAVE_CONTEXT()
  31. {
  32. LocationToRestore = OldValue;
  33. }
  34. };
  35. class POINTER_BUFFER_SWAP_CONTEXT
  36. {
  37. MIDL_STUB_MESSAGE *pStubMsg;
  38. uchar *pBufferSave;
  39. const bool DoSwap;
  40. public:
  41. __forceinline POINTER_BUFFER_SWAP_CONTEXT( MIDL_STUB_MESSAGE *pStubMsgNew ) :
  42. pStubMsg( pStubMsgNew ),
  43. DoSwap( pStubMsg->PointerBufferMark != NULL )
  44. {
  45. if ( DoSwap )
  46. {
  47. pBufferSave = pStubMsg->Buffer;
  48. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  49. pStubMsg->PointerBufferMark = 0;
  50. }
  51. }
  52. __forceinline ~POINTER_BUFFER_SWAP_CONTEXT()
  53. {
  54. if ( DoSwap )
  55. {
  56. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  57. pStubMsg->Buffer = pBufferSave;
  58. }
  59. }
  60. };
  61. class POINTER_BUFFERLENGTH_SWAP_CONTEXT
  62. {
  63. MIDL_STUB_MESSAGE *pStubMsg;
  64. ulong LengthSave;
  65. const bool DoSwap;
  66. public:
  67. __forceinline POINTER_BUFFERLENGTH_SWAP_CONTEXT( MIDL_STUB_MESSAGE *pStubMsgNew ) :
  68. pStubMsg( pStubMsgNew ),
  69. DoSwap( pStubMsg->PointerBufferMark != NULL )
  70. {
  71. if ( DoSwap )
  72. {
  73. LengthSave = pStubMsg->BufferLength;
  74. pStubMsg->BufferLength = PtrToUlong(pStubMsg->PointerBufferMark);
  75. pStubMsg->PointerBufferMark = 0;
  76. }
  77. }
  78. __forceinline ~POINTER_BUFFERLENGTH_SWAP_CONTEXT()
  79. {
  80. if ( DoSwap )
  81. {
  82. pStubMsg->PointerBufferMark = (uchar *) UlongToPtr(pStubMsg->BufferLength);
  83. pStubMsg->BufferLength = LengthSave;
  84. }
  85. }
  86. };
  87. class POINTER_MEMSIZE_SWAP_CONTEXT
  88. {
  89. MIDL_STUB_MESSAGE *pStubMsg;
  90. ulong MemorySave;
  91. uchar *pBufferSave;
  92. const bool DoSwap;
  93. public:
  94. __forceinline POINTER_MEMSIZE_SWAP_CONTEXT( MIDL_STUB_MESSAGE *pStubMsgNew ) :
  95. pStubMsg( pStubMsgNew ),
  96. DoSwap( pStubMsg->PointerBufferMark != 0 )
  97. {
  98. if ( DoSwap )
  99. {
  100. MemorySave = pStubMsg->MemorySize;
  101. pBufferSave = pStubMsg->Buffer;
  102. pStubMsg->MemorySize = pStubMsg->PointerLength;
  103. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  104. pStubMsg->PointerBufferMark = 0;
  105. pStubMsg->PointerLength = 0;
  106. }
  107. }
  108. __forceinline ~POINTER_MEMSIZE_SWAP_CONTEXT()
  109. {
  110. if ( DoSwap )
  111. {
  112. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  113. pStubMsg->PointerLength = pStubMsg->MemorySize;
  114. pStubMsg->Buffer = pBufferSave;
  115. pStubMsg->MemorySize = MemorySave;
  116. }
  117. }
  118. };
  119. class NDR_POINTER_QUEUE;
  120. struct NDR_POINTER_QUEUE_STATE;
  121. class NDR_POINTER_QUEUE_ELEMENT
  122. {
  123. public:
  124. NDR_POINTER_QUEUE_ELEMENT *pNext;
  125. virtual void Dispatch( MIDL_STUB_MESSAGE *pStubMsg ) = 0;
  126. #if defined(DBG)
  127. virtual void Print() = 0;
  128. #endif
  129. // All of these elements are allocated from a special memory pool.
  130. // Define these after NDR_POINTER_QUEUE_STATE is defined.
  131. void * operator new( size_t /*stAllocateBlock */, NDR_POINTER_QUEUE_STATE *pAllocator );
  132. void operator delete( void *pThis, NDR_POINTER_QUEUE_STATE *pAllocator );
  133. };
  134. class NDR_MRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  135. {
  136. private:
  137. uchar * const pBufferMark;
  138. uchar * const pMemory;
  139. const PFORMAT_STRING pFormat;
  140. uchar * const Memory;
  141. const uchar uFlags;
  142. public:
  143. NDR_MRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  144. uchar * const pBufferMarkNew,
  145. uchar * const pMemoryNew,
  146. const PFORMAT_STRING pFormatNew);
  147. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  148. #if defined(DBG)
  149. virtual void Print();
  150. #endif
  151. };
  152. class NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  153. {
  154. private:
  155. uchar * const pMemory;
  156. const PFORMAT_STRING pFormat;
  157. unsigned long * const pWireMarkerPtr;
  158. public:
  159. NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  160. PFORMAT_STRING pFormatNew,
  161. unsigned long *pWireMarkerPtrNew ) :
  162. pMemory( pMemoryNew ),
  163. pFormat( pFormatNew ),
  164. pWireMarkerPtr( pWireMarkerPtrNew )
  165. {}
  166. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  167. #if defined(DBG)
  168. virtual void Print();
  169. #endif
  170. };
  171. class NDR_BUFSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  172. {
  173. private:
  174. uchar * const pMemory;
  175. const PFORMAT_STRING pFormat;
  176. uchar * const Memory;
  177. const uchar uFlags;
  178. public:
  179. NDR_BUFSIZE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  180. uchar * const pMemoryNew,
  181. const PFORMAT_STRING pFormatNew);
  182. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  183. #if defined(DBG)
  184. virtual void Print();
  185. #endif
  186. };
  187. class NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  188. {
  189. private:
  190. uchar * const pMemory;
  191. const PFORMAT_STRING pFormat;
  192. public:
  193. NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  194. PFORMAT_STRING pFormatNew ) :
  195. pMemory( pMemoryNew ),
  196. pFormat( pFormatNew )
  197. {}
  198. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  199. #if defined(DBG)
  200. virtual void Print();
  201. #endif
  202. };
  203. class NDR_FREE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  204. {
  205. private:
  206. uchar * const pMemory;
  207. const PFORMAT_STRING pFormat;
  208. uchar * const Memory;
  209. const uchar uFlags;
  210. public:
  211. NDR_FREE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  212. uchar * const pMemoryNew,
  213. const PFORMAT_STRING pFormatNew);
  214. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  215. #if defined(DBG)
  216. virtual void Print();
  217. #endif
  218. };
  219. class NDR_PFNFREE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  220. {
  221. public:
  222. typedef void (__RPC_API * FREEFUNC)(void *);
  223. private:
  224. FREEFUNC pfnFree;
  225. uchar *pMemory;
  226. public:
  227. NDR_PFNFREE_POINTER_QUEUE_ELEMENT(
  228. FREEFUNC pfnFreeNew,
  229. uchar *pMemoryNew) :
  230. pfnFree(pfnFreeNew),
  231. pMemory(pMemoryNew)
  232. {
  233. }
  234. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg) {(*pfnFree)(pMemory);}
  235. virtual void Print()
  236. {
  237. DbgPrint("NDR_PFNFREE_POINTER_QUEUE_ELEMENT\n");
  238. DbgPrint("pfnFree: %p\n", pfnFree );
  239. DbgPrint("pMemory: %p\n", pMemory );
  240. }
  241. };
  242. class NDR_UNMRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  243. {
  244. private:
  245. uchar ** const ppMemory;
  246. uchar * const pMemory;
  247. long * const pBufferPointer;
  248. const PFORMAT_STRING pFormat;
  249. uchar * const Memory;
  250. const uchar uFlags;
  251. const int fInDontFree;
  252. uchar * const pCorrMemory;
  253. NDR_ALLOC_ALL_NODES_CONTEXT *const pAllocAllNodesContext;
  254. public:
  255. NDR_UNMRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  256. uchar ** ppMemoryNew,
  257. uchar * pMemoryNew,
  258. long * pBufferPointerNew,
  259. PFORMAT_STRING pFormatNew );
  260. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  261. #if defined(DBG)
  262. virtual void Print();
  263. #endif
  264. };
  265. class NDR_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  266. {
  267. private:
  268. uchar * const pMemory;
  269. const PFORMAT_STRING pFormat;
  270. public:
  271. NDR_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  272. PFORMAT_STRING pFormatNew ) :
  273. pMemory( pMemoryNew ),
  274. pFormat( pFormatNew )
  275. {}
  276. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  277. #if defined(DBG)
  278. virtual void Print();
  279. #endif
  280. };
  281. class NDR_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  282. {
  283. private:
  284. const PFORMAT_STRING pFormat;
  285. uchar * const pBufferMark;
  286. uchar * const Memory;
  287. const uchar uFlags;
  288. public:
  289. NDR_MEMSIZE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  290. uchar * pBufferMarkNew,
  291. PFORMAT_STRING pFormatNew );
  292. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  293. #if defined(DBG)
  294. virtual void Print();
  295. #endif
  296. };
  297. class NDR_CONVERT_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  298. {
  299. private:
  300. const PFORMAT_STRING pFormat;
  301. uchar * const pBufferMark;
  302. const uchar uFlags;
  303. public:
  304. NDR_CONVERT_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  305. uchar * pBufferMarkNew,
  306. PFORMAT_STRING pFormatNew );
  307. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  308. #if defined(DBG)
  309. virtual void Print() {};
  310. #endif
  311. };
  312. class NDR_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  313. {
  314. private:
  315. const PFORMAT_STRING pFormat;
  316. public:
  317. NDR_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT( PFORMAT_STRING pFormatNew ) :
  318. pFormat( pFormatNew )
  319. {}
  320. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  321. #if defined(DBG)
  322. virtual void Print();
  323. #endif
  324. };
  325. //
  326. // NDR64 Queue Elements
  327. class NDR64_MRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  328. {
  329. private:
  330. NDR64_PTR_WIRE_TYPE * const pBufferMark;
  331. uchar * const pMemory;
  332. const PFORMAT_STRING pFormat;
  333. uchar * const pCorrMemory;
  334. const uchar uFlags;
  335. public:
  336. NDR64_MRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  337. NDR64_PTR_WIRE_TYPE * const pBufferMarkNew,
  338. uchar * const pMemoryNew,
  339. const PFORMAT_STRING pFormatNew);
  340. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  341. #if defined(DBG)
  342. virtual void Print();
  343. #endif
  344. };
  345. class NDR64_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  346. {
  347. private:
  348. uchar * const pMemory;
  349. const PFORMAT_STRING pFormat;
  350. NDR64_PTR_WIRE_TYPE * const pWireMarkerPtr;
  351. public:
  352. NDR64_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  353. PFORMAT_STRING pFormatNew,
  354. NDR64_PTR_WIRE_TYPE *pWireMarkerPtrNew ) :
  355. pMemory( pMemoryNew ),
  356. pFormat( pFormatNew ),
  357. pWireMarkerPtr( pWireMarkerPtrNew )
  358. {}
  359. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  360. #if defined(DBG)
  361. virtual void Print();
  362. #endif
  363. };
  364. class NDR64_BUFSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  365. {
  366. private:
  367. NDR64_PTR_WIRE_TYPE *pBufferMark;
  368. uchar * pMemory;
  369. PFORMAT_STRING pFormat;
  370. uchar * pCorrMemory;
  371. uchar uFlags;
  372. public:
  373. NDR64_BUFSIZE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  374. uchar * const pMemoryNew,
  375. const PFORMAT_STRING pFormatNew);
  376. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  377. #if defined(DBG)
  378. virtual void Print();
  379. #endif
  380. };
  381. class NDR64_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  382. {
  383. private:
  384. uchar * const pMemory;
  385. const PFORMAT_STRING pFormat;
  386. public:
  387. NDR64_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  388. PFORMAT_STRING pFormatNew ) :
  389. pMemory( pMemoryNew ),
  390. pFormat( pFormatNew )
  391. {}
  392. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  393. #if defined(DBG)
  394. virtual void Print();
  395. #endif
  396. };
  397. class NDR64_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  398. {
  399. private:
  400. const PFORMAT_STRING pFormat;
  401. const uchar uFlags;
  402. NDR64_PTR_WIRE_TYPE * const pBufferMark;
  403. public:
  404. NDR64_MEMSIZE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  405. PFORMAT_STRING pFormatNew,
  406. NDR64_PTR_WIRE_TYPE *pBufferMarkNew ) :
  407. pFormat( pFormatNew ),
  408. uFlags( pStubMsg->uFlags ),
  409. pBufferMark( pBufferMarkNew )
  410. {}
  411. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  412. #if defined(DBG)
  413. virtual void Print();
  414. #endif
  415. };
  416. class NDR64_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  417. {
  418. private:
  419. const PFORMAT_STRING pFormat;
  420. public:
  421. NDR64_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT( PFORMAT_STRING pFormatNew ) :
  422. pFormat( pFormatNew )
  423. {}
  424. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  425. #if defined(DBG)
  426. virtual void Print();
  427. #endif
  428. };
  429. class NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  430. {
  431. private:
  432. NDR64_PTR_WIRE_TYPE WirePtr;
  433. uchar ** ppMemory;
  434. uchar * pMemory;
  435. PFORMAT_STRING pFormat;
  436. uchar * pCorrMemory;
  437. NDR_ALLOC_ALL_NODES_CONTEXT *pAllocAllNodesContext;
  438. BOOL fInDontFree;
  439. uchar uFlags;
  440. public:
  441. NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  442. uchar ** ppMemoryNew,
  443. uchar * pMemoryNew,
  444. NDR64_PTR_WIRE_TYPE WirePtrNew,
  445. PFORMAT_STRING pFormatNew );
  446. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  447. #if defined(DBG)
  448. virtual void Print();
  449. #endif
  450. };
  451. class NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  452. {
  453. private:
  454. uchar * const pMemory;
  455. const PFORMAT_STRING pFormat;
  456. public:
  457. NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  458. PFORMAT_STRING pFormatNew ) :
  459. pMemory( pMemoryNew ),
  460. pFormat( pFormatNew )
  461. {}
  462. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  463. #if defined(DBG)
  464. virtual void Print();
  465. #endif
  466. };
  467. class NDR64_FREE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  468. {
  469. private:
  470. uchar * const pMemory;
  471. const PFORMAT_STRING pFormat;
  472. uchar * const pCorrMemory;
  473. const uchar uFlags;
  474. public:
  475. NDR64_FREE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  476. uchar * const pMemoryNew,
  477. const PFORMAT_STRING pFormatNew);
  478. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  479. #if defined(DBG)
  480. virtual void Print();
  481. #endif
  482. };
  483. const SIZE_T Ndr32MaxPointerQueueElement =
  484. max(sizeof(NDR_MRSHL_POINTER_QUEUE_ELEMENT),
  485. max(sizeof(NDR_BUFSIZE_POINTER_QUEUE_ELEMENT),
  486. max(sizeof(NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT),
  487. max(sizeof(NDR_FREE_POINTER_QUEUE_ELEMENT),
  488. max(sizeof(NDR_PFNFREE_POINTER_QUEUE_ELEMENT),
  489. max(sizeof(NDR_UNMRSHL_POINTER_QUEUE_ELEMENT),
  490. max(sizeof(NDR_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT),
  491. max(sizeof(NDR_MEMSIZE_POINTER_QUEUE_ELEMENT),
  492. max(sizeof(NDR_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT),
  493. 0)))))))));
  494. const SIZE_T Ndr64MaxPointerQueueElement =
  495. max(sizeof(NDR64_MRSHL_POINTER_QUEUE_ELEMENT),
  496. max(sizeof(NDR64_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT),
  497. max(sizeof(NDR64_BUFSIZE_POINTER_QUEUE_ELEMENT),
  498. max(sizeof(NDR64_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT),
  499. max(sizeof(NDR64_MEMSIZE_POINTER_QUEUE_ELEMENT),
  500. max(sizeof(NDR64_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT),
  501. max(sizeof(NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT),
  502. max(sizeof(NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT),
  503. max(sizeof(NDR64_FREE_POINTER_QUEUE_ELEMENT),
  504. 0)))))))));
  505. const SIZE_T NdrMaxPointerQueueElement =
  506. max(Ndr32MaxPointerQueueElement,
  507. max(Ndr64MaxPointerQueueElement,
  508. 0));
  509. struct NDR_POINTER_QUEUE_STATE
  510. {
  511. private:
  512. NDR_POINTER_QUEUE *pActiveQueue;
  513. ARRAY_INFO ArrayInfo;
  514. public:
  515. NDR_POINTER_QUEUE_STATE(void) :
  516. pActiveQueue(NULL)
  517. {
  518. }
  519. virtual NDR_POINTER_QUEUE_ELEMENT *Allocate() = 0;
  520. virtual void Free(NDR_POINTER_QUEUE_ELEMENT *pElement) = 0;
  521. NDR_POINTER_QUEUE* GetActiveQueue() { return pActiveQueue; }
  522. void SetActiveQueue(NDR_POINTER_QUEUE *pNewQueue) { pActiveQueue = pNewQueue; }
  523. ARRAY_INFO * GetArrayInfo( ) {return &ArrayInfo;}
  524. };
  525. inline void *
  526. NDR_POINTER_QUEUE_ELEMENT::operator new(
  527. size_t /*stAllocateBlock */,
  528. NDR_POINTER_QUEUE_STATE *pAllocator )
  529. {
  530. return pAllocator->Allocate();
  531. }
  532. inline void
  533. NDR_POINTER_QUEUE_ELEMENT::operator delete(
  534. void *pThis,
  535. NDR_POINTER_QUEUE_STATE *pAllocator )
  536. {
  537. pAllocator->Free( (NDR_POINTER_QUEUE_ELEMENT*)pThis );
  538. }
  539. class NDR32_POINTER_QUEUE_STATE : public NDR_POINTER_QUEUE_STATE
  540. {
  541. public:
  542. // Make this private for a C compiler bug.
  543. static const ItemsToAllocate = 100;
  544. private:
  545. NDR_POINTER_QUEUE_ELEMENT *pFreeList;
  546. struct AllocationElement
  547. {
  548. SIZE_T ItemsAllocated;
  549. struct AllocationElement *pNext;
  550. // Should be pointer aligned
  551. char Data[ItemsToAllocate][NdrMaxPointerQueueElement];
  552. } *pAllocationList;
  553. void FreeAll();
  554. NDR_POINTER_QUEUE_ELEMENT *InternalAllocate();
  555. public:
  556. NDR32_POINTER_QUEUE_STATE( MIDL_STUB_MESSAGE *pStubMsg ) :
  557. pFreeList(NULL),
  558. pAllocationList(NULL)
  559. {
  560. }
  561. ~NDR32_POINTER_QUEUE_STATE() { if ( pAllocationList ) FreeAll(); }
  562. NDR_POINTER_QUEUE_ELEMENT *Allocate();
  563. void Free(NDR_POINTER_QUEUE_ELEMENT *pElement);
  564. void* operator new(size_t, void *pMemory) { return pMemory; }
  565. void operator delete(void *,void *) {return; }
  566. void operator delete(void *) {}
  567. };
  568. #if defined(BUILD_NDR64)
  569. class NDR64_POINTER_QUEUE_STATE : public NDR_POINTER_QUEUE_STATE
  570. {
  571. private:
  572. NDR_PROC_CONTEXT * const pProcContext;
  573. public:
  574. NDR64_POINTER_QUEUE_STATE(
  575. MIDL_STUB_MESSAGE *pStubMsg ) :
  576. pProcContext( (NDR_PROC_CONTEXT*)pStubMsg->pContext )
  577. {
  578. }
  579. NDR_POINTER_QUEUE_ELEMENT *Allocate();
  580. void Free(NDR_POINTER_QUEUE_ELEMENT *pElement);
  581. void* operator new(size_t, void *pMemory) { return pMemory;}
  582. void operator delete(void *,void *) {}
  583. void operator delete(void *) {}
  584. };
  585. #endif
  586. class NDR_POINTER_QUEUE
  587. {
  588. PMIDL_STUB_MESSAGE pStubMsg;
  589. NDR_POINTER_QUEUE_STATE *pQueueState;
  590. class STORAGE
  591. {
  592. NDR_POINTER_QUEUE_ELEMENT *pHead, *pPrevHead;
  593. NDR_POINTER_QUEUE_ELEMENT **pInsertPointer, **pPrevInsertPointer;
  594. public:
  595. STORAGE( );
  596. void MergeContext();
  597. void NewContext();
  598. void InsertTail( NDR_POINTER_QUEUE_ELEMENT *pNewNode );
  599. NDR_POINTER_QUEUE_ELEMENT *RemoveHead();
  600. } Storage;
  601. public:
  602. NDR_POINTER_QUEUE( PMIDL_STUB_MESSAGE pStubMsg, NDR_POINTER_QUEUE_STATE *pQueueState );
  603. void Enque( NDR_POINTER_QUEUE_ELEMENT *pElement );
  604. void Dispatch();
  605. void* operator new(size_t, void *pMemory) { return pMemory; }
  606. void operator delete(void *,void *) {return; }
  607. void operator delete(void *) {}
  608. };
  609. template<class T>
  610. class NDR_POINTER_CONTEXT
  611. {
  612. private:
  613. bool bNewState;
  614. bool bNewQueue;
  615. MIDL_STUB_MESSAGE * const pStubMsg;
  616. // Should be pointer aligned
  617. char PointerQueueStateStorage[sizeof(T)];
  618. NDR_POINTER_QUEUE *pActiveQueue;
  619. // Should be pointer aligned
  620. char PointerQueueStorage[sizeof(NDR_POINTER_QUEUE)];
  621. public:
  622. __forceinline NDR_POINTER_QUEUE_STATE *GetActiveState() { return pStubMsg->pPointerQueueState; }
  623. private:
  624. __forceinline bool IsStateActive() { return NULL != GetActiveState();}
  625. public:
  626. NDR_POINTER_CONTEXT( MIDL_STUB_MESSAGE *pStubMsgNew ) :
  627. pStubMsg( pStubMsgNew ),
  628. bNewState( false ),
  629. bNewQueue( false ),
  630. pActiveQueue( NULL )
  631. {
  632. NDR_ASSERT( NdrIsLowStack( pStubMsg ), "Created Pointer context too early.\n");
  633. if ( !IsStateActive() )
  634. {
  635. // The queue state wasn't created.
  636. pStubMsg->pPointerQueueState =
  637. new(PointerQueueStateStorage) T(pStubMsg);
  638. pActiveQueue =
  639. new(PointerQueueStorage) NDR_POINTER_QUEUE( pStubMsg, GetActiveState() );
  640. GetActiveState()->SetActiveQueue( pActiveQueue );
  641. bNewState = bNewQueue = true;
  642. return;
  643. }
  644. // State already exists
  645. pActiveQueue = GetActiveState()->GetActiveQueue();
  646. if ( pActiveQueue )
  647. return;
  648. // Already have a state, but no active queue.
  649. // Activate the queue.
  650. pActiveQueue = new(PointerQueueStorage) NDR_POINTER_QUEUE( pStubMsg, GetActiveState() );
  651. GetActiveState()->SetActiveQueue( pActiveQueue );
  652. bNewQueue = true;
  653. }
  654. __forceinline void DispatchIfRequired( )
  655. {
  656. if ( bNewQueue )
  657. {
  658. pActiveQueue->Dispatch();
  659. }
  660. }
  661. __forceinline bool ShouldEnque() { return pActiveQueue != NULL; }
  662. __forceinline void Enque( NDR_POINTER_QUEUE_ELEMENT *pElement )
  663. {
  664. pActiveQueue->Enque( pElement );
  665. }
  666. // REVIEW: Replace with a destructor once native
  667. // exception handling is enabled for ndr.
  668. __forceinline void EndContext()
  669. {
  670. if ( bNewQueue )
  671. {
  672. GetActiveState()->SetActiveQueue(NULL);
  673. }
  674. if ( bNewState)
  675. {
  676. delete (T*)GetActiveState();
  677. pStubMsg->pPointerQueueState = NULL;
  678. }
  679. }
  680. };
  681. typedef NDR_POINTER_CONTEXT<NDR32_POINTER_QUEUE_STATE> NDR32_POINTER_CONTEXT;
  682. #if defined(BUILD_NDR64)
  683. typedef NDR_POINTER_CONTEXT<NDR64_POINTER_QUEUE_STATE> NDR64_POINTER_CONTEXT;
  684. #endif
  685. #endif // __POINTER32_H__