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.

798 lines
22 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_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  298. {
  299. private:
  300. const PFORMAT_STRING pFormat;
  301. public:
  302. NDR_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT( PFORMAT_STRING pFormatNew ) :
  303. pFormat( pFormatNew )
  304. {}
  305. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  306. #if defined(DBG)
  307. virtual void Print();
  308. #endif
  309. };
  310. //
  311. // NDR64 Queue Elements
  312. class NDR64_MRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  313. {
  314. private:
  315. NDR64_PTR_WIRE_TYPE * const pBufferMark;
  316. uchar * const pMemory;
  317. const PFORMAT_STRING pFormat;
  318. uchar * const pCorrMemory;
  319. const uchar uFlags;
  320. public:
  321. NDR64_MRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  322. NDR64_PTR_WIRE_TYPE * const pBufferMarkNew,
  323. uchar * const pMemoryNew,
  324. const PFORMAT_STRING pFormatNew);
  325. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  326. #if defined(DBG)
  327. virtual void Print();
  328. #endif
  329. };
  330. class NDR64_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  331. {
  332. private:
  333. uchar * const pMemory;
  334. const PFORMAT_STRING pFormat;
  335. NDR64_PTR_WIRE_TYPE * const pWireMarkerPtr;
  336. public:
  337. NDR64_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  338. PFORMAT_STRING pFormatNew,
  339. NDR64_PTR_WIRE_TYPE *pWireMarkerPtrNew ) :
  340. pMemory( pMemoryNew ),
  341. pFormat( pFormatNew ),
  342. pWireMarkerPtr( pWireMarkerPtrNew )
  343. {}
  344. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  345. #if defined(DBG)
  346. virtual void Print();
  347. #endif
  348. };
  349. class NDR64_BUFSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  350. {
  351. private:
  352. NDR64_PTR_WIRE_TYPE *pBufferMark;
  353. uchar * pMemory;
  354. PFORMAT_STRING pFormat;
  355. uchar * pCorrMemory;
  356. uchar uFlags;
  357. public:
  358. NDR64_BUFSIZE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  359. uchar * const pMemoryNew,
  360. const PFORMAT_STRING pFormatNew);
  361. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  362. #if defined(DBG)
  363. virtual void Print();
  364. #endif
  365. };
  366. class NDR64_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  367. {
  368. private:
  369. uchar * const pMemory;
  370. const PFORMAT_STRING pFormat;
  371. public:
  372. NDR64_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  373. PFORMAT_STRING pFormatNew ) :
  374. pMemory( pMemoryNew ),
  375. pFormat( pFormatNew )
  376. {}
  377. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  378. #if defined(DBG)
  379. virtual void Print();
  380. #endif
  381. };
  382. class NDR64_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  383. {
  384. private:
  385. const PFORMAT_STRING pFormat;
  386. const uchar uFlags;
  387. NDR64_PTR_WIRE_TYPE * const pBufferMark;
  388. public:
  389. NDR64_MEMSIZE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  390. PFORMAT_STRING pFormatNew,
  391. NDR64_PTR_WIRE_TYPE *pBufferMarkNew ) :
  392. pFormat( pFormatNew ),
  393. uFlags( pStubMsg->uFlags ),
  394. pBufferMark( pBufferMarkNew )
  395. {}
  396. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  397. #if defined(DBG)
  398. virtual void Print();
  399. #endif
  400. };
  401. class NDR64_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  402. {
  403. private:
  404. const PFORMAT_STRING pFormat;
  405. public:
  406. NDR64_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT( PFORMAT_STRING pFormatNew ) :
  407. pFormat( pFormatNew )
  408. {}
  409. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  410. #if defined(DBG)
  411. virtual void Print();
  412. #endif
  413. };
  414. class NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  415. {
  416. private:
  417. NDR64_PTR_WIRE_TYPE WirePtr;
  418. uchar ** ppMemory;
  419. uchar * pMemory;
  420. PFORMAT_STRING pFormat;
  421. uchar * pCorrMemory;
  422. NDR_ALLOC_ALL_NODES_CONTEXT *pAllocAllNodesContext;
  423. BOOL fInDontFree;
  424. uchar uFlags;
  425. public:
  426. NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  427. uchar ** ppMemoryNew,
  428. uchar * pMemoryNew,
  429. NDR64_PTR_WIRE_TYPE WirePtrNew,
  430. PFORMAT_STRING pFormatNew );
  431. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  432. #if defined(DBG)
  433. virtual void Print();
  434. #endif
  435. };
  436. class NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  437. {
  438. private:
  439. uchar * const pMemory;
  440. const PFORMAT_STRING pFormat;
  441. public:
  442. NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT( uchar * pMemoryNew,
  443. PFORMAT_STRING pFormatNew ) :
  444. pMemory( pMemoryNew ),
  445. pFormat( pFormatNew )
  446. {}
  447. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  448. #if defined(DBG)
  449. virtual void Print();
  450. #endif
  451. };
  452. class NDR64_FREE_POINTER_QUEUE_ELEMENT : public NDR_POINTER_QUEUE_ELEMENT
  453. {
  454. private:
  455. uchar * const pMemory;
  456. const PFORMAT_STRING pFormat;
  457. uchar * const pCorrMemory;
  458. const uchar uFlags;
  459. public:
  460. NDR64_FREE_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg,
  461. uchar * const pMemoryNew,
  462. const PFORMAT_STRING pFormatNew);
  463. virtual void Dispatch(MIDL_STUB_MESSAGE *pStubMsg);
  464. #if defined(DBG)
  465. virtual void Print();
  466. #endif
  467. };
  468. const SIZE_T Ndr32MaxPointerQueueElement =
  469. max(sizeof(NDR_MRSHL_POINTER_QUEUE_ELEMENT),
  470. max(sizeof(NDR_BUFSIZE_POINTER_QUEUE_ELEMENT),
  471. max(sizeof(NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT),
  472. max(sizeof(NDR_FREE_POINTER_QUEUE_ELEMENT),
  473. max(sizeof(NDR_PFNFREE_POINTER_QUEUE_ELEMENT),
  474. max(sizeof(NDR_UNMRSHL_POINTER_QUEUE_ELEMENT),
  475. max(sizeof(NDR_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT),
  476. max(sizeof(NDR_MEMSIZE_POINTER_QUEUE_ELEMENT),
  477. max(sizeof(NDR_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT),
  478. 0)))))))));
  479. const SIZE_T Ndr64MaxPointerQueueElement =
  480. max(sizeof(NDR64_MRSHL_POINTER_QUEUE_ELEMENT),
  481. max(sizeof(NDR64_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT),
  482. max(sizeof(NDR64_BUFSIZE_POINTER_QUEUE_ELEMENT),
  483. max(sizeof(NDR64_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT),
  484. max(sizeof(NDR64_MEMSIZE_POINTER_QUEUE_ELEMENT),
  485. max(sizeof(NDR64_USR_MRSHL_MEMSIZE_POINTER_QUEUE_ELEMENT),
  486. max(sizeof(NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT),
  487. max(sizeof(NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT),
  488. max(sizeof(NDR64_FREE_POINTER_QUEUE_ELEMENT),
  489. 0)))))))));
  490. const SIZE_T NdrMaxPointerQueueElement =
  491. max(Ndr32MaxPointerQueueElement,
  492. max(Ndr64MaxPointerQueueElement,
  493. 0));
  494. struct NDR_POINTER_QUEUE_STATE
  495. {
  496. private:
  497. NDR_POINTER_QUEUE *pActiveQueue;
  498. public:
  499. NDR_POINTER_QUEUE_STATE(void) :
  500. pActiveQueue(NULL)
  501. {
  502. }
  503. virtual NDR_POINTER_QUEUE_ELEMENT *Allocate() = 0;
  504. virtual void Free(NDR_POINTER_QUEUE_ELEMENT *pElement) = 0;
  505. NDR_POINTER_QUEUE* GetActiveQueue() { return pActiveQueue; }
  506. void SetActiveQueue(NDR_POINTER_QUEUE *pNewQueue) { pActiveQueue = pNewQueue; }
  507. };
  508. inline void *
  509. NDR_POINTER_QUEUE_ELEMENT::operator new(
  510. size_t /*stAllocateBlock */,
  511. NDR_POINTER_QUEUE_STATE *pAllocator )
  512. {
  513. return pAllocator->Allocate();
  514. }
  515. inline void
  516. NDR_POINTER_QUEUE_ELEMENT::operator delete(
  517. void *pThis,
  518. NDR_POINTER_QUEUE_STATE *pAllocator )
  519. {
  520. pAllocator->Free( (NDR_POINTER_QUEUE_ELEMENT*)pThis );
  521. }
  522. class NDR32_POINTER_QUEUE_STATE : public NDR_POINTER_QUEUE_STATE
  523. {
  524. public:
  525. // Make this private for a C compiler bug.
  526. static const ItemsToAllocate = 100;
  527. private:
  528. NDR_POINTER_QUEUE_ELEMENT *pFreeList;
  529. struct AllocationElement
  530. {
  531. SIZE_T ItemsAllocated;
  532. struct AllocationElement *pNext;
  533. // Should be pointer aligned
  534. char Data[ItemsToAllocate][NdrMaxPointerQueueElement];
  535. } *pAllocationList;
  536. void FreeAll();
  537. NDR_POINTER_QUEUE_ELEMENT *InternalAllocate();
  538. public:
  539. NDR32_POINTER_QUEUE_STATE( MIDL_STUB_MESSAGE *pStubMsg ) :
  540. pFreeList(NULL),
  541. pAllocationList(NULL)
  542. {
  543. }
  544. ~NDR32_POINTER_QUEUE_STATE() { if ( pAllocationList ) FreeAll(); }
  545. NDR_POINTER_QUEUE_ELEMENT *Allocate();
  546. void Free(NDR_POINTER_QUEUE_ELEMENT *pElement);
  547. void* operator new(size_t, void *pMemory) { return pMemory; }
  548. void operator delete(void *,void *) {return; }
  549. void operator delete(void *) {}
  550. };
  551. #if defined(BUILD_NDR64)
  552. class NDR64_POINTER_QUEUE_STATE : public NDR_POINTER_QUEUE_STATE
  553. {
  554. private:
  555. NDR_PROC_CONTEXT * const pProcContext;
  556. public:
  557. NDR64_POINTER_QUEUE_STATE(
  558. MIDL_STUB_MESSAGE *pStubMsg ) :
  559. pProcContext( (NDR_PROC_CONTEXT*)pStubMsg->pContext )
  560. {
  561. }
  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 *) {}
  566. void operator delete(void *) {}
  567. };
  568. #endif
  569. class NDR_POINTER_QUEUE
  570. {
  571. PMIDL_STUB_MESSAGE pStubMsg;
  572. NDR_POINTER_QUEUE_STATE *pQueueState;
  573. class STORAGE
  574. {
  575. NDR_POINTER_QUEUE_ELEMENT *pHead, *pPrevHead;
  576. NDR_POINTER_QUEUE_ELEMENT **pInsertPointer, **pPrevInsertPointer;
  577. public:
  578. STORAGE( );
  579. void MergeContext();
  580. void NewContext();
  581. void InsertTail( NDR_POINTER_QUEUE_ELEMENT *pNewNode );
  582. NDR_POINTER_QUEUE_ELEMENT *RemoveHead();
  583. } Storage;
  584. public:
  585. NDR_POINTER_QUEUE( PMIDL_STUB_MESSAGE pStubMsg, NDR_POINTER_QUEUE_STATE *pQueueState );
  586. void Enque( NDR_POINTER_QUEUE_ELEMENT *pElement );
  587. void Dispatch();
  588. void* operator new(size_t, void *pMemory) { return pMemory; }
  589. void operator delete(void *,void *) {return; }
  590. void operator delete(void *) {}
  591. };
  592. template<class T>
  593. class NDR_POINTER_CONTEXT
  594. {
  595. private:
  596. bool bNewState;
  597. bool bNewQueue;
  598. MIDL_STUB_MESSAGE * const pStubMsg;
  599. // Should be pointer aligned
  600. char PointerQueueStateStorage[sizeof(T)];
  601. NDR_POINTER_QUEUE *pActiveQueue;
  602. // Should be pointer aligned
  603. char PointerQueueStorage[sizeof(NDR_POINTER_QUEUE)];
  604. public:
  605. __forceinline NDR_POINTER_QUEUE_STATE *GetActiveState() { return pStubMsg->pPointerQueueState; }
  606. private:
  607. __forceinline bool IsStateActive() { return NULL != GetActiveState();}
  608. public:
  609. NDR_POINTER_CONTEXT( MIDL_STUB_MESSAGE *pStubMsgNew ) :
  610. pStubMsg( pStubMsgNew ),
  611. bNewState( false ),
  612. bNewQueue( false ),
  613. pActiveQueue( NULL )
  614. {
  615. NDR_ASSERT( NdrIsLowStack( pStubMsg ), "Created Pointer context too early.\n");
  616. if ( !IsStateActive() )
  617. {
  618. // The queue state wasn't created.
  619. pStubMsg->pPointerQueueState =
  620. new(PointerQueueStateStorage) T(pStubMsg);
  621. pActiveQueue =
  622. new(PointerQueueStorage) NDR_POINTER_QUEUE( pStubMsg, GetActiveState() );
  623. GetActiveState()->SetActiveQueue( pActiveQueue );
  624. bNewState = bNewQueue = true;
  625. return;
  626. }
  627. // State already exists
  628. pActiveQueue = GetActiveState()->GetActiveQueue();
  629. if ( pActiveQueue )
  630. return;
  631. // Already have a state, but no active queue.
  632. // Activate the queue.
  633. pActiveQueue = new(PointerQueueStorage) NDR_POINTER_QUEUE( pStubMsg, GetActiveState() );
  634. GetActiveState()->SetActiveQueue( pActiveQueue );
  635. bNewQueue = true;
  636. }
  637. __forceinline void DispatchIfRequired( )
  638. {
  639. if ( bNewQueue )
  640. {
  641. pActiveQueue->Dispatch();
  642. }
  643. }
  644. __forceinline bool ShouldEnque() { return pActiveQueue != NULL; }
  645. __forceinline void Enque( NDR_POINTER_QUEUE_ELEMENT *pElement )
  646. {
  647. pActiveQueue->Enque( pElement );
  648. }
  649. // REVIEW: Replace with a destructor once native
  650. // exception handling is enabled for ndr.
  651. __forceinline void EndContext()
  652. {
  653. if ( bNewQueue )
  654. {
  655. GetActiveState()->SetActiveQueue(NULL);
  656. }
  657. if ( bNewState)
  658. {
  659. delete (T*)GetActiveState();
  660. pStubMsg->pPointerQueueState = NULL;
  661. }
  662. }
  663. };
  664. typedef NDR_POINTER_CONTEXT<NDR32_POINTER_QUEUE_STATE> NDR32_POINTER_CONTEXT;
  665. #if defined(BUILD_NDR64)
  666. typedef NDR_POINTER_CONTEXT<NDR64_POINTER_QUEUE_STATE> NDR64_POINTER_CONTEXT;
  667. #endif
  668. #endif // __POINTER32_H__