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.

3001 lines
80 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name :
  4. bufsize.c
  5. Abstract :
  6. This file contains the routines called by MIDL 2.0 stubs and the
  7. interpreter for computing the buffer size needed for a parameter.
  8. Author :
  9. David Kays dkays September 1993.
  10. Revision History :
  11. ---------------------------------------------------------------------*/
  12. #include "ndrp.h"
  13. #include "ndrole.h"
  14. #include "attack.h"
  15. #include "pointerq.h"
  16. RPCRTAPI
  17. void RPC_ENTRY
  18. NdrUDTSimpleTypeSize(
  19. PMIDL_STUB_MESSAGE pStubMsg,
  20. unsigned char * pMemory,
  21. PFORMAT_STRING pFormat
  22. );
  23. extern const
  24. PSIZE_ROUTINE SizeRoutinesTable[] =
  25. {
  26. NdrUDTSimpleTypeSize,
  27. NdrUDTSimpleTypeSize,
  28. NdrUDTSimpleTypeSize,
  29. NdrUDTSimpleTypeSize,
  30. NdrUDTSimpleTypeSize,
  31. NdrUDTSimpleTypeSize,
  32. NdrUDTSimpleTypeSize,
  33. NdrUDTSimpleTypeSize,
  34. NdrUDTSimpleTypeSize,
  35. NdrUDTSimpleTypeSize,
  36. NdrUDTSimpleTypeSize,
  37. NdrUDTSimpleTypeSize,
  38. NdrUDTSimpleTypeSize,
  39. NdrUDTSimpleTypeSize,
  40. NdrUDTSimpleTypeSize,
  41. NdrUDTSimpleTypeSize,
  42. NdrUDTSimpleTypeSize,
  43. NdrPointerBufferSize,
  44. NdrPointerBufferSize,
  45. NdrPointerBufferSize,
  46. NdrPointerBufferSize,
  47. NdrSimpleStructBufferSize,
  48. NdrSimpleStructBufferSize,
  49. NdrConformantStructBufferSize,
  50. NdrConformantStructBufferSize,
  51. NdrConformantVaryingStructBufferSize,
  52. NdrComplexStructBufferSize,
  53. NdrConformantArrayBufferSize,
  54. NdrConformantVaryingArrayBufferSize,
  55. NdrFixedArrayBufferSize,
  56. NdrFixedArrayBufferSize,
  57. NdrVaryingArrayBufferSize,
  58. NdrVaryingArrayBufferSize,
  59. NdrComplexArrayBufferSize,
  60. NdrConformantStringBufferSize,
  61. NdrConformantStringBufferSize,
  62. NdrConformantStringBufferSize,
  63. NdrConformantStringBufferSize,
  64. NdrNonConformantStringBufferSize,
  65. NdrNonConformantStringBufferSize,
  66. NdrNonConformantStringBufferSize,
  67. NdrNonConformantStringBufferSize,
  68. NdrEncapsulatedUnionBufferSize,
  69. NdrNonEncapsulatedUnionBufferSize,
  70. NdrByteCountPointerBufferSize,
  71. NdrXmitOrRepAsBufferSize, // transmit as
  72. NdrXmitOrRepAsBufferSize, // represent as
  73. NdrPointerBufferSize,
  74. NdrContextHandleSize,
  75. // New Post NT 3.5 token serviced from here on.
  76. 0, // NdrHardStructBufferSize,
  77. NdrXmitOrRepAsBufferSize, // transmit as ptr
  78. NdrXmitOrRepAsBufferSize, // represent as ptr
  79. NdrUserMarshalBufferSize,
  80. 0, // FC_PIPE
  81. 0, // FC_BLK_HOLE
  82. NdrpRangeBufferSize,
  83. 0, // FC_INT3264
  84. 0, // FC_UINT3264
  85. 0, // NdrCsArrayBufferSize,
  86. 0, // NdrCsTagBufferSize
  87. };
  88. const
  89. PSIZE_ROUTINE * pfnSizeRoutines = SizeRoutinesTable;
  90. void
  91. NdrpInterfacePointerBufferSize (
  92. PMIDL_STUB_MESSAGE pStubMsg,
  93. uchar * pMemory,
  94. PFORMAT_STRING pFormat );
  95. RPCRTAPI
  96. void RPC_ENTRY
  97. NdrTypeSize(
  98. PMIDL_STUB_MESSAGE pStubMsg,
  99. unsigned char * pMemory,
  100. PFORMAT_STRING pFormat
  101. )
  102. {
  103. (*pfnSizeRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  104. pMemory,
  105. pFormat );
  106. }
  107. void RPC_ENTRY
  108. NdrUDTSimpleTypeSize(
  109. PMIDL_STUB_MESSAGE pStubMsg,
  110. uchar * pMemory,
  111. PFORMAT_STRING pFormat )
  112. /*++
  113. Routine Description :
  114. Get the size a top level or embedded simple type.
  115. Used for VT_USERDEFINED but in fact simple types,
  116. like TKIND_ENUM and TKIND_ALIAS
  117. Arguments :
  118. pStubMsg - Pointer to the stub message.
  119. pMemory - Pointer to the data being sized.
  120. pFormat - Pointer's format string description.
  121. Return :
  122. None.
  123. --*/
  124. {
  125. LENGTH_ALIGN( pStubMsg->BufferLength,
  126. SIMPLE_TYPE_ALIGNMENT(*pFormat) );
  127. pStubMsg->BufferLength += SIMPLE_TYPE_BUFSIZE(*pFormat);
  128. pMemory += SIMPLE_TYPE_MEMSIZE(*pFormat);
  129. }
  130. void RPC_ENTRY
  131. NdrPointerBufferSize(
  132. PMIDL_STUB_MESSAGE pStubMsg,
  133. uchar * pMemory,
  134. PFORMAT_STRING pFormat )
  135. /*++
  136. Routine Description :
  137. Computes the needed buffer size for a top level pointer to anything.
  138. Pointers embedded in structures, arrays, or unions call
  139. NdrpPointerBufferSize directly.
  140. Used for FC_RP, FC_UP, FC_FP, FC_OP.
  141. Arguments :
  142. pStubMsg - Pointer to the stub message.
  143. pMemory - Pointer to the data being sized.
  144. pFormat - Pointer's format string description.
  145. Return :
  146. None.
  147. --*/
  148. {
  149. //
  150. // Add 4 bytes for a unique or full pointer.
  151. //
  152. if ( *pFormat != FC_RP )
  153. {
  154. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  155. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  156. }
  157. NdrpPointerBufferSize( pStubMsg,
  158. pMemory,
  159. pFormat );
  160. }
  161. __forceinline void
  162. NdrpPointerBufferSizeInternal(
  163. PMIDL_STUB_MESSAGE pStubMsg,
  164. uchar * pMemory,
  165. PFORMAT_STRING pFormat )
  166. /*++
  167. Routine Description :
  168. Private routine for sizing a pointee. This is the entry
  169. point for pointers embedded in structures, arrays, or unions.
  170. Used for FC_RP, FC_UP, FC_FP, FC_OP.
  171. Arguments :
  172. pStubMsg - Pointer to the stub message.
  173. pMemory - Pointer to the data being sized.
  174. pFormat - Pointer's format string description.
  175. pStubMsg->BufferLength - ready for the pointee.
  176. Return :
  177. None.
  178. --*/
  179. {
  180. if ( FC_IP == *pFormat )
  181. {
  182. if ( IS_BROKEN_INTERFACE_POINTER(pStubMsg->uFlags) )
  183. {
  184. // The pointee is effectivly both the pointer
  185. // and the pointee.
  186. NdrInterfacePointerBufferSize(
  187. pStubMsg,
  188. pMemory,
  189. pFormat );
  190. return;
  191. }
  192. if ( ! pMemory )
  193. return;
  194. NdrpInterfacePointerBufferSize( pStubMsg,
  195. pMemory,
  196. pFormat );
  197. return;
  198. }
  199. uchar uFlagsSave;
  200. if ( ! pMemory )
  201. return;
  202. if ( *pFormat == FC_FP )
  203. {
  204. //
  205. // Check if we have already sized this full pointer.
  206. //
  207. if ( NdrFullPointerQueryPointer( pStubMsg->FullPtrXlatTables,
  208. pMemory,
  209. FULL_POINTER_BUF_SIZED,
  210. 0 ) )
  211. return;
  212. }
  213. if ( ! SIMPLE_POINTER(pFormat[1]) )
  214. {
  215. //
  216. // Pointer to complex type.
  217. //
  218. if ( POINTER_DEREF(pFormat[1]) )
  219. pMemory = *((uchar **)pMemory);
  220. pFormat += 2;
  221. pFormat += *((signed short *)pFormat);
  222. }
  223. else
  224. {
  225. switch ( pFormat[2] )
  226. {
  227. case FC_C_CSTRING :
  228. case FC_C_BSTRING :
  229. case FC_C_WSTRING :
  230. case FC_C_SSTRING :
  231. // Increment to the string description.
  232. pFormat += 2;
  233. break;
  234. default :
  235. //
  236. // Pointer to simple type. Make an upper bound estimate.
  237. //
  238. SIMPLE_TYPE_BUF_INCREMENT(pStubMsg->BufferLength, pFormat[2]);
  239. return;
  240. }
  241. }
  242. uFlagsSave = pStubMsg->uFlags;
  243. RESET_CONF_FLAGS_TO_STANDALONE(pStubMsg->uFlags);
  244. (*pfnSizeRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  245. pMemory,
  246. pFormat );
  247. pStubMsg->uFlags = uFlagsSave;
  248. }
  249. NDR_BUFSIZE_POINTER_QUEUE_ELEMENT::NDR_BUFSIZE_POINTER_QUEUE_ELEMENT(
  250. MIDL_STUB_MESSAGE *pStubMsg,
  251. uchar * const pMemoryNew,
  252. const PFORMAT_STRING pFormatNew) :
  253. pMemory(pMemoryNew),
  254. pFormat(pFormatNew),
  255. Memory(pStubMsg->Memory),
  256. uFlags(pStubMsg->uFlags)
  257. {
  258. }
  259. void
  260. NDR_BUFSIZE_POINTER_QUEUE_ELEMENT::Dispatch(
  261. MIDL_STUB_MESSAGE *pStubMsg)
  262. {
  263. SAVE_CONTEXT<uchar*> MemorySave( pStubMsg->Memory, Memory );
  264. SAVE_CONTEXT<uchar> uFlagsSave( pStubMsg->uFlags, uFlags );
  265. NDR_ASSERT( !pStubMsg->PointerBufferMark, "PointerBufferMark is not 0\n");
  266. NdrpPointerBufferSizeInternal( pStubMsg,
  267. pMemory,
  268. pFormat );
  269. }
  270. #if defined(DBG)
  271. void
  272. NDR_BUFSIZE_POINTER_QUEUE_ELEMENT::Print()
  273. {
  274. DbgPrint("NDR_BUFSIZE_POINTER_QUEUE_ELEMENT\n");
  275. DbgPrint("pNext: %p\n", pNext );
  276. DbgPrint("pMemory: %p\n", pMemory );
  277. DbgPrint("pFormat: %p\n", pFormat );
  278. DbgPrint("Memory: %p\n", Memory );
  279. DbgPrint("uFlags: %x\n", uFlags );
  280. }
  281. #endif
  282. void
  283. NdrpEnquePointerBufferSize(
  284. PMIDL_STUB_MESSAGE pStubMsg,
  285. uchar * pMemory,
  286. PFORMAT_STRING pFormat )
  287. {
  288. NDR32_POINTER_CONTEXT PointerContext( pStubMsg );
  289. RpcTryFinally
  290. {
  291. NDR_BUFSIZE_POINTER_QUEUE_ELEMENT *pElement =
  292. new(PointerContext.GetActiveState())
  293. NDR_BUFSIZE_POINTER_QUEUE_ELEMENT(pStubMsg,
  294. pMemory,
  295. pFormat);
  296. PointerContext.Enque( pElement );
  297. PointerContext.DispatchIfRequired();
  298. }
  299. RpcFinally
  300. {
  301. PointerContext.EndContext();
  302. }
  303. RpcEndFinally
  304. }
  305. void
  306. NdrpPointerBufferSize(
  307. PMIDL_STUB_MESSAGE pStubMsg,
  308. uchar * pMemory,
  309. PFORMAT_STRING pFormat )
  310. {
  311. if ( !NdrIsLowStack( pStubMsg ) )
  312. {
  313. NdrpPointerBufferSizeInternal( pStubMsg,
  314. pMemory,
  315. pFormat );
  316. return;
  317. }
  318. NdrpEnquePointerBufferSize(
  319. pStubMsg,
  320. pMemory,
  321. pFormat );
  322. }
  323. void RPC_ENTRY
  324. NdrpRangeBufferSize(
  325. PMIDL_STUB_MESSAGE pStubMsg,
  326. uchar * pMemory,
  327. PFORMAT_STRING pFormat )
  328. /*++
  329. Routine Description :
  330. Computes the buffer size needed for a simple type with range on it.
  331. Used for FC_RANGE.
  332. Arguments :
  333. pStubMsg - Pointer to the stub message.
  334. pMemory - Pointer to the structure being sized.
  335. pFormat - Structure's format string description.
  336. Return :
  337. None.
  338. --*/
  339. {
  340. // This routine is needed because the precomputed buf size is missing in some cases.
  341. // So it is cheaper to have the routine than to change code paths elsewhere.
  342. FORMAT_CHARACTER FcType = (FORMAT_CHARACTER)(pFormat[1] & 0x0f);
  343. LENGTH_ALIGN( pStubMsg->BufferLength, SIMPLE_TYPE_ALIGNMENT(FcType) );
  344. pStubMsg->BufferLength += SIMPLE_TYPE_BUFSIZE(FcType);
  345. }
  346. void RPC_ENTRY
  347. NdrSimpleStructBufferSize(
  348. PMIDL_STUB_MESSAGE pStubMsg,
  349. uchar * pMemory,
  350. PFORMAT_STRING pFormat )
  351. /*++
  352. Routine Description :
  353. Computes the buffer size needed for a simple structure.
  354. Used for FC_STRUCT and FC_PSTRUCT.
  355. Arguments :
  356. pStubMsg - Pointer to the stub message.
  357. pMemory - Pointer to the structure being sized.
  358. pFormat - Structure's format string description.
  359. Return :
  360. None.
  361. --*/
  362. {
  363. LENGTH_ALIGN(pStubMsg->BufferLength,pFormat[1]);
  364. // Add size of the structure.
  365. pStubMsg->BufferLength += (ulong) *((ushort *)(pFormat + 2));
  366. //
  367. // Add size of embedded pointers.
  368. //
  369. if ( *pFormat == FC_PSTRUCT )
  370. {
  371. NdrpEmbeddedPointerBufferSize( pStubMsg,
  372. pMemory,
  373. pFormat + 4 );
  374. }
  375. }
  376. void RPC_ENTRY
  377. NdrConformantStructBufferSize(
  378. PMIDL_STUB_MESSAGE pStubMsg,
  379. uchar * pMemory,
  380. PFORMAT_STRING pFormat )
  381. /*++
  382. Routine Description :
  383. Computes the buffer size needed for a conformant structure.
  384. Used for FC_CSTRUCT and FC_CPSTRUCT.
  385. Arguments :
  386. pStubMsg - Pointer to the stub message.
  387. pMemory - Pointer to the structure being sized.
  388. pFormat - Structure's format string description.
  389. Return :
  390. None.
  391. --*/
  392. {
  393. PFORMAT_STRING pFormatArray;
  394. ulong FlatSize;
  395. // set by the embedding complex struct
  396. uchar fIsEmbeddedStructSave = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  397. // accounted for by the outermost embedding complex struct
  398. if ( !fIsEmbeddedStructSave )
  399. {
  400. // Align and add size for conformance count.
  401. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  402. pStubMsg->BufferLength += 4;
  403. }
  404. // Align
  405. LENGTH_ALIGN(pStubMsg->BufferLength, pFormat[1] );
  406. FlatSize = (ulong) *((ushort *)(pFormat + 2));
  407. pStubMsg->BufferLength += FlatSize;
  408. // Increment to the offset to array description.
  409. pFormat += 4;
  410. pFormatArray = pFormat + *((signed short *)pFormat);
  411. //
  412. // Size our array - pass a memory pointer to the conformant array.
  413. //
  414. NdrpConformantArrayBufferSize( pStubMsg,
  415. pMemory + FlatSize,
  416. pFormatArray );
  417. pFormat += 2;
  418. if ( *pFormat == FC_PP )
  419. {
  420. NdrpEmbeddedPointerBufferSize( pStubMsg,
  421. pMemory,
  422. pFormat );
  423. }
  424. // Set the reverse flag to signal that array has been marshaled.
  425. if ( fIsEmbeddedStructSave )
  426. SET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  427. }
  428. void RPC_ENTRY
  429. NdrConformantVaryingStructBufferSize(
  430. PMIDL_STUB_MESSAGE pStubMsg,
  431. uchar * pMemory,
  432. PFORMAT_STRING pFormat )
  433. /*++
  434. Routine Description :
  435. Computes the buffer size needed for a conformant varying structure.
  436. Used for FC_CVSTRUCT.
  437. Arguments :
  438. pStubMsg - Pointer to the stub message.
  439. pMemory - Pointer to the structure being sized.
  440. pFormat - Structure's format string description.
  441. Return :
  442. None.
  443. --*/
  444. {
  445. PPRIVATE_SIZE_ROUTINE pfnSize;
  446. PFORMAT_STRING pFormatArray;
  447. ulong FlatSize;
  448. // set by the outermost embedding complex struct
  449. uchar fIsEmbeddedStructSave = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  450. // accounted for by the outermost embedding complex struct
  451. if ( !fIsEmbeddedStructSave )
  452. {
  453. // Align
  454. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  455. pStubMsg->BufferLength += 4;
  456. }
  457. // Align
  458. LENGTH_ALIGN(pStubMsg->BufferLength, pFormat[1] );
  459. FlatSize = (ulong) *((ushort *)(pFormat + 2));
  460. pStubMsg->BufferLength += FlatSize;
  461. // Increment to the offset to array description.
  462. pFormat += 4;
  463. pFormatArray = pFormat + *((signed short *)pFormat);
  464. switch ( *pFormatArray )
  465. {
  466. case FC_CVARRAY :
  467. pfnSize = NdrpConformantVaryingArrayBufferSize;
  468. break;
  469. default :
  470. pfnSize = NdrpConformantStringBufferSize;
  471. break;
  472. }
  473. (*pfnSize)( pStubMsg,
  474. pMemory + FlatSize,
  475. pFormatArray );
  476. pFormat += 2;
  477. if ( *pFormat == FC_PP )
  478. {
  479. pStubMsg->MaxCount = pStubMsg->ActualCount;
  480. NdrpEmbeddedPointerBufferSize( pStubMsg,
  481. pMemory,
  482. pFormat );
  483. }
  484. // Set the reverse flag to signal that array has been marshaled.
  485. if ( fIsEmbeddedStructSave )
  486. SET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  487. }
  488. #if 0
  489. void RPC_ENTRY
  490. NdrHardStructBufferSize(
  491. PMIDL_STUB_MESSAGE pStubMsg,
  492. uchar * pMemory,
  493. PFORMAT_STRING pFormat )
  494. /*++
  495. Routine Description :
  496. Computes the buffer size needed for a hard structure.
  497. Used for FC_HARD_STRUCT.
  498. Arguments :
  499. pStubMsg - Pointer to the stub message.
  500. pMemory - Pointer to the structure being sized.
  501. pFormat - Structure's format string description.
  502. Return :
  503. None.
  504. --*/
  505. {
  506. LENGTH_ALIGN(pStubMsg->BufferLength,pFormat[1]);
  507. pStubMsg->BufferLength += *((ushort *)&pFormat[10]);
  508. if ( *((short *)&pFormat[14]) )
  509. {
  510. pFormat += 12;
  511. pMemory += *((ushort *)pFormat)++;
  512. pFormat += *((short *)pFormat);
  513. (*pfnSizeRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  514. pMemory,
  515. pFormat );
  516. }
  517. }
  518. #endif // 0
  519. void RPC_ENTRY
  520. NdrComplexStructBufferSize(
  521. PMIDL_STUB_MESSAGE pStubMsg,
  522. uchar * pMemory,
  523. PFORMAT_STRING pFormat )
  524. /*++
  525. Routine Description :
  526. Computes the buffer size needed for a complex structure.
  527. Used for FC_BOGUS_STRUCT.
  528. Arguments :
  529. pStubMsg - Pointer to the stub message.
  530. pMemory - Pointer to the structure being sized.
  531. pFormat - Structure's format string description.
  532. Return :
  533. None.
  534. --*/
  535. {
  536. PFORMAT_STRING pFormatPointers;
  537. PFORMAT_STRING pFormatArray;
  538. PFORMAT_STRING pFormatComplex;
  539. long Alignment;
  540. long Align8Mod;
  541. BOOL fEmbedConfStructContext;
  542. uchar* pMemoryLoop;
  543. PFORMAT_STRING pFormatLoop;
  544. uchar fIsEmbeddedStructSave = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  545. uchar * pMemorySave = pStubMsg->Memory;
  546. //
  547. // If were not ignoring pointees and the the stub message PointerBufferMark field is 0,
  548. // then determine the position in the buffer where pointees will be marshalled.
  549. //
  550. // We have to do this to handle embedded pointers.
  551. //
  552. bool fSetPointerBufferMark = !pStubMsg->IgnoreEmbeddedPointers &&
  553. !pStubMsg->PointerBufferMark;
  554. if ( fSetPointerBufferMark )
  555. {
  556. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  557. ulong BufferLengthSave = pStubMsg->BufferLength;
  558. NdrComplexStructBufferSize( pStubMsg,
  559. pMemory,
  560. pFormat );
  561. // If the size of the flat part is zero and this is the first item to be
  562. // marshalled, add a small offset to the buffer so that we can continue
  563. // to use PointerBufferMark as an is embedded flag.
  564. if ( !pStubMsg->BufferLength)
  565. {
  566. pStubMsg->BufferLength += NDR_MAX_BUFFER_ALIGNMENT;
  567. BufferLengthSave += NDR_MAX_BUFFER_ALIGNMENT;
  568. }
  569. pStubMsg->IgnoreEmbeddedPointers = FALSE;
  570. pStubMsg->PointerBufferMark = (uchar *) UlongToPtr(pStubMsg->BufferLength);
  571. pStubMsg->BufferLength = BufferLengthSave;
  572. }
  573. //
  574. // This is used when computing the count(s) for size_is or length_is
  575. // pointers.
  576. //
  577. pStubMsg->Memory = pMemory;
  578. Alignment = pFormat[1];
  579. //
  580. // This is used for support of structs with doubles passed on an
  581. // i386 stack, and of struct with longs on 16 bit platforms.
  582. //
  583. // A cast to long is what we need.
  584. Align8Mod = 0x7 & PtrToLong( pMemory );
  585. pFormat += 4;
  586. fEmbedConfStructContext = fIsEmbeddedStructSave;
  587. // Get conformant array description.
  588. if ( *((ushort *)pFormat) )
  589. {
  590. pFormatArray = pFormat + *((signed short *)pFormat);
  591. // mark Complex struct embedding Conformant struct case
  592. if ( FixWireRepForDComVerGTE54( pStubMsg ) )
  593. fEmbedConfStructContext = TRUE;
  594. // accounted for by the outermost embedding complex struct
  595. if ( !fIsEmbeddedStructSave )
  596. {
  597. //
  598. // Align and add size of conformance count(s).
  599. //
  600. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  601. pStubMsg->BufferLength += 4 * NdrpArrayDimensions( pStubMsg,
  602. pFormatArray,
  603. FALSE);
  604. }
  605. }
  606. else
  607. pFormatArray = 0;
  608. RESET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  609. pFormat += 2;
  610. // Get pointer layout description.
  611. if ( *((ushort *)pFormat) )
  612. pFormatPointers = pFormat + *((ushort *)pFormat);
  613. else
  614. pFormatPointers = 0;
  615. pFormat += 2;
  616. // save variables for second loop
  617. pMemoryLoop = pMemory;
  618. pFormatLoop = pFormat;
  619. LENGTH_ALIGN(pStubMsg->BufferLength,Alignment);
  620. //
  621. // size the structure member by member.
  622. //
  623. for ( ; *pFormat != FC_END; pFormat++ )
  624. {
  625. switch ( *pFormat )
  626. {
  627. //
  628. // simple types
  629. //
  630. case FC_CHAR :
  631. case FC_BYTE :
  632. case FC_SMALL :
  633. case FC_WCHAR :
  634. case FC_SHORT :
  635. case FC_LONG :
  636. #if defined(__RPC_WIN64__)
  637. case FC_INT3264:
  638. case FC_UINT3264:
  639. #endif
  640. case FC_FLOAT :
  641. case FC_HYPER :
  642. case FC_DOUBLE :
  643. case FC_ENUM16 :
  644. case FC_ENUM32 :
  645. case FC_IGNORE :
  646. LENGTH_ALIGN( pStubMsg->BufferLength,
  647. SIMPLE_TYPE_ALIGNMENT(*pFormat) );
  648. pStubMsg->BufferLength += SIMPLE_TYPE_BUFSIZE(*pFormat);
  649. pMemory += SIMPLE_TYPE_MEMSIZE(*pFormat);
  650. break;
  651. case FC_POINTER :
  652. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  653. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  654. if ( !pStubMsg->IgnoreEmbeddedPointers )
  655. {
  656. POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext( pStubMsg );
  657. NdrpPointerBufferSize( pStubMsg,
  658. *((uchar **)pMemory),
  659. pFormatPointers );
  660. }
  661. pFormatPointers += 4;
  662. pMemory += PTR_MEM_SIZE;
  663. break;
  664. //
  665. // Embedded complex types.
  666. //
  667. case FC_EMBEDDED_COMPLEX :
  668. // Add padding.
  669. pMemory += pFormat[1];
  670. pFormat += 2;
  671. // Get the type's description.
  672. pFormatComplex = pFormat + *((signed short UNALIGNED *)pFormat);
  673. if ( FC_IP == *pFormatComplex )
  674. {
  675. // Treat embedded interface pointers the same as regular pointers.
  676. LENGTH_ALIGN( pStubMsg->BufferLength, 0x3 );
  677. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  678. if ( !pStubMsg->IgnoreEmbeddedPointers )
  679. {
  680. POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext( pStubMsg );
  681. NdrpPointerBufferSize( pStubMsg,
  682. *((uchar **)pMemory),
  683. pFormatComplex);
  684. }
  685. pMemory += PTR_MEM_SIZE;
  686. pFormat++;
  687. break;
  688. }
  689. // Needed for embedded conf structs
  690. //
  691. if ( fEmbedConfStructContext )
  692. SET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  693. (*pfnSizeRoutines[ROUTINE_INDEX(*pFormatComplex)])
  694. ( pStubMsg,
  695. pMemory,
  696. pFormatComplex );
  697. pMemory = NdrpMemoryIncrement( pStubMsg,
  698. pMemory,
  699. pFormatComplex );
  700. RESET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  701. //
  702. // Increment the main format string one byte. The loop
  703. // will increment it one more byte past the offset field.
  704. //
  705. pFormat++;
  706. break;
  707. case FC_ALIGNM2 :
  708. ALIGN( pMemory, 0x1 );
  709. break;
  710. case FC_ALIGNM4 :
  711. ALIGN( pMemory, 0x3 );
  712. break;
  713. case FC_ALIGNM8 :
  714. //
  715. // We have to play some tricks for the i386 to handle the case
  716. // when an 8 byte aligned structure is passed by value. The
  717. // alignment of the struct on the stack is not guaranteed to be
  718. // on an 8 byte boundary.
  719. //
  720. pMemory -= Align8Mod;
  721. ALIGN( pMemory, 0x7 );
  722. pMemory += Align8Mod;
  723. break;
  724. case FC_STRUCTPAD1 :
  725. case FC_STRUCTPAD2 :
  726. case FC_STRUCTPAD3 :
  727. case FC_STRUCTPAD4 :
  728. case FC_STRUCTPAD5 :
  729. case FC_STRUCTPAD6 :
  730. case FC_STRUCTPAD7 :
  731. pMemory += (*pFormat - FC_STRUCTPAD1) + 1;
  732. break;
  733. case FC_STRUCTPADN :
  734. // FC_STRUCTPADN 0 <unsigned short>
  735. pMemory += *(((unsigned short *)pFormat) + 1);
  736. pFormat += 3;
  737. break;
  738. case FC_PAD :
  739. break;
  740. //
  741. // Done with layout.
  742. //
  743. case FC_END :
  744. break;
  745. default :
  746. NDR_ASSERT(0,"NdrComplexStructBufferSize : bad format char");
  747. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  748. return;
  749. } // switch
  750. } // for
  751. //
  752. // Size any conformant array.
  753. //
  754. // accounted for by the outermost embedding complex struct
  755. // .. but not when embedded and not when array done by an embeded conf struct.
  756. if ( pFormatArray && !fIsEmbeddedStructSave &&
  757. ! IS_CONF_ARRAY_DONE( pStubMsg->uFlags ) )
  758. {
  759. PPRIVATE_SIZE_ROUTINE pfnSize;
  760. switch ( *pFormatArray )
  761. {
  762. case FC_CARRAY :
  763. pfnSize = NdrpConformantArrayBufferSize;
  764. break;
  765. case FC_CVARRAY :
  766. pfnSize = NdrpConformantVaryingArrayBufferSize;
  767. break;
  768. case FC_BOGUS_ARRAY :
  769. pfnSize = NdrpComplexArrayBufferSize;
  770. break;
  771. // case FC_C_WSTRING :
  772. // case FC_C_CSTRING :
  773. // case FC_C_BSTRING :
  774. // case FC_C_SSTRING :
  775. default :
  776. pfnSize = NdrpConformantStringBufferSize;
  777. break;
  778. }
  779. (*pfnSize)( pStubMsg,
  780. pMemory,
  781. pFormatArray );
  782. }
  783. if ( fIsEmbeddedStructSave )
  784. SET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  785. else
  786. RESET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  787. pStubMsg->Memory = pMemorySave;
  788. if ( fSetPointerBufferMark )
  789. {
  790. pStubMsg->BufferLength = PtrToUlong(pStubMsg->PointerBufferMark);
  791. pStubMsg->PointerBufferMark = NULL;
  792. }
  793. }
  794. void RPC_ENTRY
  795. NdrFixedArrayBufferSize(
  796. PMIDL_STUB_MESSAGE pStubMsg,
  797. uchar * pMemory,
  798. PFORMAT_STRING pFormat )
  799. /*++
  800. Routine Description :
  801. Computes the buffer size needed for a fixed array of any number of
  802. dimensions.
  803. Used for FC_SMFARRAY and FC_LGFARRAY.
  804. Arguments :
  805. pStubMsg - Pointer to the stub message.
  806. pMemory - Pointer to the array being sized.
  807. pFormat - Array's format string description.
  808. Return :
  809. None.
  810. --*/
  811. {
  812. LENGTH_ALIGN(pStubMsg->BufferLength,pFormat[1]);
  813. if ( *pFormat == FC_SMFARRAY )
  814. {
  815. pFormat += 2;
  816. pStubMsg->BufferLength += *((ushort *&)pFormat)++;
  817. }
  818. else
  819. {
  820. pFormat += 2;
  821. pStubMsg->BufferLength += *((ulong UNALIGNED *&)pFormat)++;
  822. }
  823. if ( *pFormat == FC_PP )
  824. {
  825. NdrpEmbeddedPointerBufferSize( pStubMsg,
  826. pMemory,
  827. pFormat );
  828. }
  829. }
  830. void RPC_ENTRY
  831. NdrConformantArrayBufferSize(
  832. PMIDL_STUB_MESSAGE pStubMsg,
  833. uchar * pMemory,
  834. PFORMAT_STRING pFormat )
  835. /*++
  836. Routine Description :
  837. Computes the buffer size needed for a top level one dimensional conformant
  838. array.
  839. Used for FC_CARRAY.
  840. Arguments :
  841. pStubMsg - Pointer to the stub message.
  842. pMemory - Pointer to the array being sized.
  843. pFormat - Array's format string description.
  844. Return :
  845. None.
  846. --*/
  847. {
  848. //
  849. // Align and add size for conformance count.
  850. //
  851. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  852. pStubMsg->BufferLength += 4;
  853. NdrpConformantArrayBufferSize( pStubMsg,
  854. pMemory,
  855. pFormat );
  856. }
  857. void
  858. NdrpConformantArrayBufferSize(
  859. PMIDL_STUB_MESSAGE pStubMsg,
  860. uchar * pMemory,
  861. PFORMAT_STRING pFormat )
  862. /*++
  863. Routine Description :
  864. Private routine for computing the buffer size needed for a one dimensional
  865. conformant array. This is the entry point for unmarshalling an embedded
  866. conformant array.
  867. Used for FC_CARRAY.
  868. Arguments :
  869. pStubMsg - Pointer to the stub message.
  870. pMemory - Pointer to the array being sized.
  871. pFormat - Array's format string description.
  872. Return :
  873. None.
  874. --*/
  875. {
  876. ulong ConformanceCount;
  877. ConformanceCount = (ulong) NdrpComputeConformance( pStubMsg,
  878. pMemory,
  879. pFormat );
  880. if ( ((long)ConformanceCount) < 0 )
  881. RpcRaiseException( RPC_X_INVALID_BOUND );
  882. if ( ! ConformanceCount )
  883. return;
  884. LENGTH_ALIGN(pStubMsg->BufferLength,pFormat[1]);
  885. pFormat += 2;
  886. // Add array size.
  887. pStubMsg->BufferLength += *((ushort *)pFormat) * ConformanceCount;
  888. pFormat += 6;
  889. CORRELATION_DESC_INCREMENT( pFormat );
  890. if ( *pFormat == FC_PP )
  891. {
  892. NdrpEmbeddedPointerBufferSize( pStubMsg,
  893. pMemory,
  894. pFormat );
  895. }
  896. }
  897. void RPC_ENTRY
  898. NdrConformantVaryingArrayBufferSize(
  899. PMIDL_STUB_MESSAGE pStubMsg,
  900. uchar * pMemory,
  901. PFORMAT_STRING pFormat )
  902. /*++
  903. Routine Description :
  904. Computes the buffer size needed for a top level one dimensional conformant
  905. varying array.
  906. Used for FC_CVARRAY.
  907. Arguments :
  908. pStubMsg - Pointer to the stub message.
  909. pMemory - Pointer to the array being sized.
  910. pFormat - Array's format string description.
  911. Return :
  912. None.
  913. --*/
  914. {
  915. //
  916. // Align and add size for conformance count.
  917. //
  918. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  919. pStubMsg->BufferLength += 4;
  920. NdrpConformantVaryingArrayBufferSize( pStubMsg,
  921. pMemory,
  922. pFormat );
  923. }
  924. void
  925. NdrpConformantVaryingArrayBufferSize(
  926. PMIDL_STUB_MESSAGE pStubMsg,
  927. uchar * pMemory,
  928. PFORMAT_STRING pFormat )
  929. /*++
  930. Routine Description :
  931. Private routine for computing the buffer size needed for a one dimensional
  932. conformant varying array. This is the entry point for buffer sizing an
  933. embedded conformant varying array.
  934. Used for FC_CVARRAY.
  935. Arguments :
  936. pStubMsg - Pointer to the stub message.
  937. pMemory - Pointer to the array being sized.
  938. pFormat - Array's format string description.
  939. Return :
  940. None.
  941. --*/
  942. {
  943. ulong ConformanceCount;
  944. //
  945. // Align and add size for offset and actual count.
  946. //
  947. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  948. pStubMsg->BufferLength += 8;
  949. NdrpComputeVariance( pStubMsg,
  950. pMemory,
  951. pFormat );
  952. // Check if the bounds are valid
  953. ConformanceCount = (ulong) NdrpComputeConformance( pStubMsg,
  954. pMemory,
  955. pFormat );
  956. if ( ( ((long)ConformanceCount) < 0 ) ||
  957. ( ((long)pStubMsg->ActualCount) < 0 ) ||
  958. ( ((long)pStubMsg->Offset) < 0 ) ||
  959. ( (pStubMsg->Offset + pStubMsg->ActualCount) > ConformanceCount ) )
  960. RpcRaiseException( RPC_X_INVALID_BOUND );
  961. if ( ! pStubMsg->ActualCount )
  962. return;
  963. LENGTH_ALIGN(pStubMsg->BufferLength, pFormat[1]);
  964. pFormat += 2;
  965. // Add array size.
  966. pStubMsg->BufferLength += *((ushort *)pFormat) * pStubMsg->ActualCount;
  967. pFormat += 10;
  968. CORRELATION_DESC_INCREMENT( pFormat );
  969. CORRELATION_DESC_INCREMENT( pFormat );
  970. if ( *pFormat == FC_PP )
  971. {
  972. //
  973. // MaxCount must contain the number of shipped elements in the array
  974. // before sizing embedded pointers.
  975. //
  976. pStubMsg->MaxCount = pStubMsg->ActualCount;
  977. NdrpEmbeddedPointerBufferSize( pStubMsg,
  978. pMemory,
  979. pFormat );
  980. }
  981. }
  982. void RPC_ENTRY
  983. NdrVaryingArrayBufferSize(
  984. PMIDL_STUB_MESSAGE pStubMsg,
  985. uchar * pMemory,
  986. PFORMAT_STRING pFormat )
  987. /*++
  988. Routine Description :
  989. Computes the buffer size needed for a top level or embedded one
  990. dimensional varying array.
  991. Used for FC_SMVARRAY and FC_LGVARRAY.
  992. Arguments :
  993. pStubMsg - Pointer to the stub message.
  994. pMemory - Pointer to the array being sized.
  995. pFormat - Array's format string description.
  996. Return :
  997. None.
  998. Arguments :
  999. pMemory - pointer to the parameter to size
  1000. pFormat - pointer to the format string description of the parameter
  1001. --*/
  1002. {
  1003. ulong Elements;
  1004. ulong ElementSize;
  1005. //
  1006. // Align and add size for offset and actual count.
  1007. //
  1008. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1009. pStubMsg->BufferLength += 8;
  1010. NdrpComputeVariance( pStubMsg,
  1011. pMemory,
  1012. pFormat );
  1013. // Check if the bounds are valid
  1014. Elements =
  1015. (*pFormat == FC_SMVARRAY) ?
  1016. *((ushort *)(pFormat + 4)) : *((ulong UNALIGNED *)(pFormat + 6));
  1017. if ( ( ((long)pStubMsg->ActualCount) < 0 ) ||
  1018. ( ((long)pStubMsg->Offset) < 0 ) ||
  1019. ( (pStubMsg->Offset + pStubMsg->ActualCount) > Elements ) )
  1020. RpcRaiseException( RPC_X_INVALID_BOUND );
  1021. if ( ! pStubMsg->ActualCount )
  1022. return;
  1023. LENGTH_ALIGN(pStubMsg->BufferLength, pFormat[1]);
  1024. if (*pFormat == FC_SMVARRAY)
  1025. {
  1026. ElementSize = *((ushort *)(pFormat + 6));
  1027. pFormat += 12;
  1028. }
  1029. else
  1030. {
  1031. ElementSize = *((ushort *)(pFormat + 10));
  1032. pFormat += 16;
  1033. }
  1034. CORRELATION_DESC_INCREMENT( pFormat );
  1035. pStubMsg->BufferLength += ElementSize * pStubMsg->ActualCount;
  1036. if ( *pFormat == FC_PP )
  1037. {
  1038. //
  1039. // MaxCount must contain the number of shipped elements in the array
  1040. // before sizing embedded pointers.
  1041. //
  1042. pStubMsg->MaxCount = pStubMsg->ActualCount;
  1043. NdrpEmbeddedPointerBufferSize( pStubMsg,
  1044. pMemory,
  1045. pFormat );
  1046. }
  1047. }
  1048. void RPC_ENTRY
  1049. NdrComplexArrayBufferSize(
  1050. PMIDL_STUB_MESSAGE pStubMsg,
  1051. uchar * pMemory,
  1052. PFORMAT_STRING pFormat )
  1053. /*++
  1054. Routine Description :
  1055. Computes the buffer size needed for a top level complex array.
  1056. Used for FC_BOGUS_STRUCT.
  1057. Arguments :
  1058. pStubMsg - Pointer to the stub message.
  1059. pMemory - Pointer to the array being sized.
  1060. pFormat - Array's format string description.
  1061. Return :
  1062. None.
  1063. Note.
  1064. Array of ref pointers does not have wire representation for the pointers
  1065. themselves, regardless whether array is top level or embedded in a struct.
  1066. --*/
  1067. {
  1068. bool fSetPointerBufferMark = !pStubMsg->IgnoreEmbeddedPointers &&
  1069. (! pStubMsg->PointerBufferMark );
  1070. if ( fSetPointerBufferMark )
  1071. {
  1072. //
  1073. // Save the current conformance and variance fields. The sizing
  1074. // routine can overwrite them.
  1075. //
  1076. ULONG_PTR MaxCountSave = pStubMsg->MaxCount;
  1077. ulong OffsetSave = pStubMsg->Offset;
  1078. ulong ActualCountSave = pStubMsg->ActualCount;
  1079. ulong BufferLengthSave = pStubMsg->BufferLength;
  1080. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  1081. NdrComplexArrayBufferSize( pStubMsg,
  1082. pMemory,
  1083. pFormat );
  1084. // If the size of the flat part is zero and this is the first item to be
  1085. // marshalled, add a small offset to the buffer so that we can continue
  1086. // to use PointerBufferMark as an is embedded flag.
  1087. if ( !pStubMsg->BufferLength)
  1088. {
  1089. pStubMsg->BufferLength += NDR_MAX_BUFFER_ALIGNMENT;
  1090. BufferLengthSave += NDR_MAX_BUFFER_ALIGNMENT;
  1091. }
  1092. pStubMsg->PointerBufferMark = (uchar *) UlongToPtr(pStubMsg->BufferLength);
  1093. pStubMsg->IgnoreEmbeddedPointers = FALSE;
  1094. // Restore conformance and variance fields.
  1095. pStubMsg->MaxCount = MaxCountSave;
  1096. pStubMsg->Offset = OffsetSave;
  1097. pStubMsg->ActualCount = ActualCountSave;
  1098. pStubMsg->BufferLength = BufferLengthSave;
  1099. }
  1100. //
  1101. // Add in conformance sizes if we are the outermost dimension.
  1102. //
  1103. if ( pStubMsg->pArrayInfo == 0 )
  1104. {
  1105. //
  1106. // Align and add size for any conformance count(s).
  1107. //
  1108. if ( *((long UNALIGNED *)(pFormat + 4)) != 0xffffffff )
  1109. {
  1110. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1111. pStubMsg->BufferLength += NdrpArrayDimensions( pStubMsg, pFormat, FALSE ) * 4;
  1112. }
  1113. }
  1114. NdrpComplexArrayBufferSize( pStubMsg,
  1115. pMemory,
  1116. pFormat );
  1117. if ( fSetPointerBufferMark )
  1118. {
  1119. pStubMsg->BufferLength = PtrToUlong(pStubMsg->PointerBufferMark);
  1120. pStubMsg->PointerBufferMark = NULL;
  1121. }
  1122. }
  1123. void
  1124. NdrpComplexArrayBufferSize(
  1125. PMIDL_STUB_MESSAGE pStubMsg,
  1126. uchar * pMemory,
  1127. PFORMAT_STRING pFormat )
  1128. /*++
  1129. Routine Description :
  1130. Private routine for determing the buffer size of a complex array. This
  1131. is the entry point for buffer sizing an embedded complex array.
  1132. Arguments :
  1133. pStubMsg - Pointer to the stub message.
  1134. pMemory - Pointer to the array being sized.
  1135. pFormat - Array's format string description.
  1136. Return :
  1137. None.
  1138. --*/
  1139. {
  1140. ARRAY_INFO ArrayInfo;
  1141. PARRAY_INFO pArrayInfo;
  1142. PSIZE_ROUTINE pfnSize;
  1143. PFORMAT_STRING pFormatStart;
  1144. ulong Elements;
  1145. ulong Offset, Count;
  1146. ulong MemoryElementSize;
  1147. long Dimension;
  1148. uchar Alignment;
  1149. //
  1150. // Lots of setup if we are the outer dimension.
  1151. //
  1152. if ( ! pStubMsg->pArrayInfo )
  1153. {
  1154. NdrpInitArrayInfo(pStubMsg, &ArrayInfo );
  1155. //
  1156. // Set this to 0 so that NdrpMemoryIncrement will know to call
  1157. // NdrpComputeConformance when computing our size.
  1158. //
  1159. pStubMsg->pArrayInfo->BufferConformanceMark = 0;
  1160. }
  1161. pFormatStart = pFormat;
  1162. pArrayInfo = pStubMsg->pArrayInfo;
  1163. Dimension = pArrayInfo->Dimension;
  1164. // Get the array alignment.
  1165. Alignment = pFormat[1];
  1166. pFormat += 2;
  1167. // Get the number of elements (0 if conformance present).
  1168. Elements = *((ushort *&)pFormat)++;
  1169. //
  1170. // Check for conformance description.
  1171. //
  1172. if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
  1173. {
  1174. Elements = (ulong) NdrpComputeConformance( pStubMsg,
  1175. pMemory,
  1176. pFormatStart );
  1177. }
  1178. pFormat += 4;
  1179. CORRELATION_DESC_INCREMENT( pFormat );
  1180. //
  1181. // Check for variance description.
  1182. //
  1183. if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
  1184. {
  1185. NdrpComputeVariance( pStubMsg,
  1186. pMemory,
  1187. pFormatStart );
  1188. Offset = pStubMsg->Offset;
  1189. Count = pStubMsg->ActualCount;
  1190. if ( Dimension == 0 )
  1191. {
  1192. //
  1193. // Align and add in size of variance count(s).
  1194. //
  1195. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1196. pStubMsg->BufferLength +=
  1197. NdrpArrayDimensions( pStubMsg, pFormatStart, TRUE ) * 8;
  1198. }
  1199. }
  1200. else
  1201. {
  1202. Offset = 0;
  1203. Count = Elements;
  1204. }
  1205. pFormat += 4;
  1206. CORRELATION_DESC_INCREMENT( pFormat );
  1207. // Check bounds
  1208. if ( ( ((long)Elements) < 0 ) ||
  1209. ( ((long)Count) < 0 ) ||
  1210. ( ((long)Offset) < 0 ) ||
  1211. ( (Offset + Count) > Elements ) )
  1212. RpcRaiseException( RPC_X_INVALID_BOUND );
  1213. if ( Count )
  1214. {
  1215. LENGTH_ALIGN( pStubMsg->BufferLength, Alignment );
  1216. if ( *pFormat == FC_EMBEDDED_COMPLEX )
  1217. {
  1218. ulong CountSave;
  1219. uchar* pMemorySave;
  1220. PFORMAT_STRING pFormatSave;
  1221. pFormat += 2;
  1222. pFormat += *((signed short *)pFormat);
  1223. if ( FC_IP == *pFormat )
  1224. goto PointerSizing;
  1225. pfnSize = pfnSizeRoutines[ROUTINE_INDEX(*pFormat)];
  1226. pArrayInfo->Dimension = Dimension + 1;
  1227. MemoryElementSize = (ulong) ( NdrpMemoryIncrement( pStubMsg,
  1228. pMemory,
  1229. pFormat ) - pMemory );
  1230. if ( ! IS_ARRAY_OR_STRING(*pFormat) )
  1231. pStubMsg->pArrayInfo = 0;
  1232. //
  1233. // If there is variance then increment the memory pointer to the first
  1234. // element actually being sized.
  1235. //
  1236. if ( Offset )
  1237. pMemory += Offset * MemoryElementSize;
  1238. pFormatSave = pFormat;
  1239. pMemorySave = pMemory;
  1240. CountSave = Count;
  1241. for ( ; Count--; )
  1242. {
  1243. // Keep track of multidimensional array dimension.
  1244. if ( IS_ARRAY_OR_STRING(*pFormat) )
  1245. pArrayInfo->Dimension = Dimension + 1;
  1246. (*pfnSize)( pStubMsg,
  1247. pMemory,
  1248. pFormat );
  1249. pMemory += MemoryElementSize;
  1250. }
  1251. pMemory += MemoryElementSize;
  1252. }
  1253. else if ( *pFormat == FC_UP || *pFormat == FC_FP || *pFormat == FC_OP || *pFormat == FC_RP ||
  1254. *pFormat == FC_IP )
  1255. {
  1256. PointerSizing:
  1257. //
  1258. // Shallow size the array
  1259. //
  1260. if ( *pFormat != FC_RP )
  1261. {
  1262. pStubMsg->BufferLength += Count * PTR_WIRE_SIZE;
  1263. }
  1264. //
  1265. // If there is variance then increment the memory pointer to the first
  1266. // element actually being sized.
  1267. //
  1268. if ( Offset )
  1269. pMemory += Offset * PTR_MEM_SIZE;
  1270. //
  1271. // size the pointees
  1272. //
  1273. if ( !pStubMsg->IgnoreEmbeddedPointers )
  1274. {
  1275. bool UseBrokenInterfacePointerRep =
  1276. (FC_IP == *pFormat) && !FixWireRepForDComVerGTE54( pStubMsg );
  1277. // If this is the broken interface pointer format, make sure we
  1278. // have enough space for both the pointer and pointee where
  1279. // the pointer should have been.
  1280. if ( UseBrokenInterfacePointerRep )
  1281. SET_BROKEN_INTERFACE_POINTER( pStubMsg->uFlags );
  1282. // Need this in case we have a variant offset.
  1283. pStubMsg->pArrayInfo = 0;
  1284. // Switch to the pointee buffer.
  1285. POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext( pStubMsg );
  1286. for ( ; Count--; )
  1287. {
  1288. NdrpPointerBufferSize(
  1289. pStubMsg,
  1290. *((uchar **&)pMemory)++,
  1291. pFormat );
  1292. }
  1293. if ( UseBrokenInterfacePointerRep )
  1294. RESET_BROKEN_INTERFACE_POINTER( pStubMsg->uFlags );
  1295. }
  1296. }
  1297. else if (*pFormat == FC_RANGE )
  1298. {
  1299. pStubMsg->BufferLength += Count * SIMPLE_TYPE_BUFSIZE( pFormat[1] );
  1300. }
  1301. else
  1302. {
  1303. NDR_ASSERT( IS_SIMPLE_TYPE(*pFormat), "NdrpComplexArrayBufferSize : bad format char" );
  1304. pStubMsg->BufferLength += Count * SIMPLE_TYPE_BUFSIZE(*pFormat);
  1305. }
  1306. }
  1307. // pArrayInfo must be zero when not valid.
  1308. pStubMsg->pArrayInfo = (Dimension == 0) ? 0 : pArrayInfo;
  1309. }
  1310. void RPC_ENTRY
  1311. NdrNonConformantStringBufferSize(
  1312. PMIDL_STUB_MESSAGE pStubMsg,
  1313. uchar * pMemory,
  1314. PFORMAT_STRING pFormat )
  1315. /*++
  1316. Routine Description :
  1317. Computes the buffer size needed for a non conformant string.
  1318. Used for FC_CSTRING, FC_WSTRING, FC_SSTRING, and FC_BSTRING (NT Beta2
  1319. compatability only).
  1320. Arguments :
  1321. pStubMsg - Pointer to the stub message.
  1322. pMemory - Pointer to the array being sized.
  1323. pFormat - Array's format string description.
  1324. Return :
  1325. None.
  1326. --*/
  1327. {
  1328. long MaxSize;
  1329. long Length;
  1330. // Align and add size for variance counts.
  1331. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1332. pStubMsg->BufferLength += 8;
  1333. switch ( *pFormat )
  1334. {
  1335. case FC_CSTRING :
  1336. case FC_BSTRING :
  1337. Length = strlen((char*)pMemory) + 1;
  1338. break;
  1339. case FC_WSTRING :
  1340. Length = (wcslen((wchar_t *)pMemory) + 1) * sizeof(wchar_t);
  1341. break;
  1342. case FC_SSTRING :
  1343. Length = NdrpStringStructLen( pMemory, pFormat[1] ) + 1;
  1344. Length *= pFormat[1];
  1345. break;
  1346. default :
  1347. NDR_ASSERT(0,"NdrNonConformantStringBufferSize : Bad format type");
  1348. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1349. return;
  1350. }
  1351. // Check bounds
  1352. MaxSize = *((ushort *)(pFormat + 2));
  1353. switch ( *pFormat )
  1354. {
  1355. case FC_WSTRING :
  1356. MaxSize *= sizeof(wchar_t);
  1357. break;
  1358. case FC_SSTRING :
  1359. MaxSize *= pFormat[1];
  1360. break;
  1361. default :
  1362. break;
  1363. }
  1364. if ( Length > MaxSize )
  1365. RpcRaiseException(RPC_X_INVALID_BOUND);
  1366. pStubMsg->BufferLength += Length;
  1367. }
  1368. void RPC_ENTRY
  1369. NdrConformantStringBufferSize(
  1370. PMIDL_STUB_MESSAGE pStubMsg,
  1371. uchar * pMemory,
  1372. PFORMAT_STRING pFormat )
  1373. /*++
  1374. Routine Description :
  1375. Computes the buffer size needed for a top level conformant string.
  1376. Used for FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and FC_C_BSTRING
  1377. (NT Beta2 compatability only).
  1378. Arguments :
  1379. pStubMsg - Pointer to the stub message.
  1380. pMemory - Pointer to the array being sized.
  1381. pFormat - Array's format string description.
  1382. Return :
  1383. None.
  1384. --*/
  1385. {
  1386. //
  1387. // Add in size for conformance marshalling only if this string is not
  1388. // in a multidimensional array.
  1389. //
  1390. if ( pStubMsg->pArrayInfo == 0 )
  1391. {
  1392. // Align and add size for conformance count.
  1393. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1394. pStubMsg->BufferLength += 4;
  1395. }
  1396. NdrpConformantStringBufferSize( pStubMsg,
  1397. pMemory,
  1398. pFormat );
  1399. }
  1400. void
  1401. NdrpConformantStringBufferSize(
  1402. PMIDL_STUB_MESSAGE pStubMsg,
  1403. uchar * pMemory,
  1404. PFORMAT_STRING pFormat )
  1405. /*++
  1406. Routine Description :
  1407. Private routine for computing the buffer size needed for a conformant
  1408. string. This is the entry point for an embedded conformant string.
  1409. Used for FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and FC_C_BSTRING
  1410. (NT Beta2 compatability only).
  1411. Arguments :
  1412. pStubMsg - Pointer to the stub message.
  1413. pMemory - Pointer to the array being sized.
  1414. pFormat - Array's format string description.
  1415. Return :
  1416. None.
  1417. --*/
  1418. {
  1419. long MaxSize;
  1420. long Length;
  1421. // Align and add size for variance.
  1422. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1423. pStubMsg->BufferLength += 8;
  1424. switch ( *pFormat )
  1425. {
  1426. case FC_C_CSTRING :
  1427. case FC_C_BSTRING :
  1428. Length = strlen((char*)pMemory) + 1;
  1429. break;
  1430. case FC_C_WSTRING :
  1431. Length = (wcslen((wchar_t *)pMemory) + 1) * sizeof(wchar_t);
  1432. break;
  1433. case FC_C_SSTRING :
  1434. Length = NdrpStringStructLen( pMemory, pFormat[1] ) + 1;
  1435. Length *= pFormat[1];
  1436. break;
  1437. default :
  1438. NDR_ASSERT(0,"NdrpConformantStringBufferSize : Bad format type");
  1439. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1440. return;
  1441. }
  1442. //
  1443. // Do bounds checking.
  1444. //
  1445. if ( ((*pFormat != FC_C_SSTRING) && (pFormat[1] == FC_STRING_SIZED)) ||
  1446. ((*pFormat == FC_C_SSTRING) && (pFormat[2] == FC_STRING_SIZED)) )
  1447. {
  1448. MaxSize = (ulong) NdrpComputeConformance( pStubMsg,
  1449. pMemory,
  1450. pFormat );
  1451. switch ( *pFormat )
  1452. {
  1453. case FC_C_WSTRING :
  1454. MaxSize *= sizeof(wchar_t);
  1455. break;
  1456. case FC_C_SSTRING :
  1457. MaxSize *= pFormat[1];
  1458. break;
  1459. default :
  1460. break;
  1461. }
  1462. if ( (MaxSize < 0) || (Length > MaxSize) )
  1463. RpcRaiseException(RPC_X_INVALID_BOUND);
  1464. }
  1465. pStubMsg->BufferLength += Length;
  1466. }
  1467. void RPC_ENTRY
  1468. NdrEncapsulatedUnionBufferSize(
  1469. PMIDL_STUB_MESSAGE pStubMsg,
  1470. uchar * pMemory,
  1471. PFORMAT_STRING pFormat )
  1472. /*++
  1473. Routine Description :
  1474. Computes the buffer size needed for an encapsulated union.
  1475. Used for FC_ENCAPSULATED_UNION.
  1476. Arguments :
  1477. pStubMsg - Pointer to the stub message.
  1478. pMemory - Pointer to the union being sized.
  1479. pFormat - Union's format string description.
  1480. Return :
  1481. None.
  1482. --*/
  1483. {
  1484. long SwitchIs;
  1485. uchar SwitchType;
  1486. NO_CORRELATION;
  1487. SwitchType = LOW_NIBBLE(pFormat[1]);
  1488. switch ( SwitchType )
  1489. {
  1490. case FC_SMALL :
  1491. case FC_CHAR :
  1492. SwitchIs = (long) *((char *)pMemory);
  1493. break;
  1494. case FC_USMALL :
  1495. SwitchIs = (long) *((uchar *)pMemory);
  1496. break;
  1497. case FC_ENUM16 :
  1498. case FC_SHORT :
  1499. SwitchIs = (long) *((short *)pMemory);
  1500. break;
  1501. case FC_USHORT :
  1502. case FC_WCHAR :
  1503. SwitchIs = (long) *((ushort *)pMemory);
  1504. break;
  1505. case FC_LONG :
  1506. case FC_ULONG :
  1507. case FC_ENUM32 :
  1508. // FC_INT3264 is mapped to FC_LONG.
  1509. SwitchIs = *((long *)pMemory);
  1510. break;
  1511. default :
  1512. NDR_ASSERT(0,"NdrEncapsulatedBufferSize : bad switch type");
  1513. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1514. return;
  1515. }
  1516. // Increment memory pointer to the union.
  1517. pMemory += HIGH_NIBBLE(pFormat[1]);
  1518. NdrpUnionBufferSize( pStubMsg,
  1519. pMemory,
  1520. pFormat + 2,
  1521. SwitchIs,
  1522. SwitchType );
  1523. }
  1524. void RPC_ENTRY
  1525. NdrNonEncapsulatedUnionBufferSize(
  1526. PMIDL_STUB_MESSAGE pStubMsg,
  1527. uchar * pMemory,
  1528. PFORMAT_STRING pFormat )
  1529. /*++
  1530. Routine Description :
  1531. Computes the buffer size needed for a non encapsulated union.
  1532. Used for FC_NON_ENCAPSULATED_UNION.
  1533. Arguments :
  1534. pStubMsg - Pointer to the stub message.
  1535. pMemory - Pointer to the union being sized.
  1536. pFormat - Union's format string description.
  1537. Return :
  1538. None.
  1539. --*/
  1540. {
  1541. long SwitchIs;
  1542. uchar SwitchType;
  1543. SwitchType = pFormat[1];
  1544. SwitchIs = (ulong) NdrpComputeSwitchIs( pStubMsg,
  1545. pMemory,
  1546. pFormat );
  1547. //
  1548. // Set the format string to the memory size and arm description.
  1549. //
  1550. pFormat += 6;
  1551. CORRELATION_DESC_INCREMENT( pFormat );
  1552. pFormat += *((signed short *)pFormat);
  1553. NdrpUnionBufferSize( pStubMsg,
  1554. pMemory,
  1555. pFormat,
  1556. SwitchIs,
  1557. SwitchType );
  1558. }
  1559. void
  1560. NdrpUnionBufferSize(
  1561. PMIDL_STUB_MESSAGE pStubMsg,
  1562. uchar * pMemory,
  1563. PFORMAT_STRING pFormat,
  1564. long SwitchIs,
  1565. uchar SwitchType )
  1566. /*++
  1567. Routine Description :
  1568. Private routine for computing the buffer size needed for a union. This
  1569. routine is used for sizing both encapsulated and non-encapsulated unions.
  1570. Arguments :
  1571. pStubMsg - Pointer to the stub message.
  1572. pMemory - Pointer to the union being sized.
  1573. pFormat - Union's format string description.
  1574. SwitchIs - The union's switch is.
  1575. SwitchType - The union's switch type.
  1576. Return :
  1577. None.
  1578. --*/
  1579. {
  1580. long Arms;
  1581. long Alignment;
  1582. //
  1583. // Size the switch_is.
  1584. //
  1585. LENGTH_ALIGN(pStubMsg->BufferLength,SIMPLE_TYPE_ALIGNMENT(SwitchType));
  1586. pStubMsg->BufferLength += SIMPLE_TYPE_BUFSIZE(SwitchType);
  1587. // Skip the memory size field.
  1588. pFormat += 2;
  1589. //
  1590. // Get the union alignment (0 if this is a DCE union) and align the
  1591. // buffer on this alignment.
  1592. //
  1593. Alignment = (uchar) ( *((ushort *)pFormat) >> 12 );
  1594. LENGTH_ALIGN(pStubMsg->BufferLength,Alignment);
  1595. Arms = (long) ( *((ushort *&)pFormat)++ & 0x0fff );
  1596. //
  1597. // Search for the arm.
  1598. //
  1599. for ( ; Arms; Arms-- )
  1600. {
  1601. if ( *((long UNALIGNED *&)pFormat)++ == SwitchIs )
  1602. {
  1603. //
  1604. // Found the right arm, break out.
  1605. //
  1606. break;
  1607. }
  1608. // Else increment format string.
  1609. pFormat += 2;
  1610. }
  1611. //
  1612. // Check if we took the default arm and no default arm is specified.
  1613. //
  1614. if ( ! Arms && (*((ushort *)pFormat) == (ushort) 0xffff) )
  1615. {
  1616. RpcRaiseException( RPC_S_INVALID_TAG );
  1617. }
  1618. //
  1619. // Return if the arm is empty.
  1620. //
  1621. if ( ! *((ushort *)pFormat) )
  1622. return;
  1623. //
  1624. // Get the arm's description.
  1625. //
  1626. // We need a real solution after beta for simple type arms. This could
  1627. // break if we have a format string larger than about 32K.
  1628. //
  1629. if ( IS_MAGIC_UNION_BYTE(pFormat) )
  1630. {
  1631. // Re-align again, only does something usefull for DCE unions.
  1632. unsigned char FcType = pFormat[0];
  1633. LENGTH_ALIGN( pStubMsg->BufferLength, SIMPLE_TYPE_ALIGNMENT( FcType ));
  1634. pStubMsg->BufferLength += SIMPLE_TYPE_BUFSIZE( FcType );
  1635. }
  1636. else
  1637. {
  1638. pFormat += *((signed short *)pFormat);
  1639. //
  1640. // If the union arm we take is a pointer, we have to dereference the
  1641. // current memory pointer since we're passed a pointer to the union
  1642. // (regardless of whether the actual parameter was a by-value union
  1643. // or a pointer to a union).
  1644. //
  1645. if ( IS_POINTER_TYPE(*pFormat) )
  1646. {
  1647. if ( pStubMsg->IgnoreEmbeddedPointers )
  1648. {
  1649. //
  1650. // If we're ignoring pointers then just add in the size of a pointer
  1651. // here and return.
  1652. //
  1653. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1654. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  1655. return;
  1656. }
  1657. pMemory = *((uchar **)pMemory);
  1658. if ( pStubMsg->PointerBufferMark )
  1659. {
  1660. // If the union is embedded, tread it specially
  1661. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1662. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  1663. if ( !pStubMsg->IgnoreEmbeddedPointers )
  1664. {
  1665. POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext(pStubMsg);
  1666. NdrpPointerBufferSize( pStubMsg,
  1667. pMemory,
  1668. pFormat );
  1669. }
  1670. return;
  1671. }
  1672. }
  1673. // Call the appropriate sizing routine
  1674. (*pfnSizeRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  1675. pMemory,
  1676. pFormat );
  1677. }
  1678. }
  1679. void RPC_ENTRY
  1680. NdrByteCountPointerBufferSize(
  1681. PMIDL_STUB_MESSAGE pStubMsg,
  1682. uchar * pMemory,
  1683. PFORMAT_STRING pFormat )
  1684. /*++
  1685. Routine Description :
  1686. Computes the buffer size needed for a byte count pointer.
  1687. Arguments :
  1688. pStubMsg - Pointer to the stub message.
  1689. pMemory - The byte count pointer being sized.
  1690. pFormat - Byte count pointer's format string description.
  1691. Return :
  1692. None.
  1693. --*/
  1694. {
  1695. //
  1696. // We don't do anything special here. Just pass things on to the
  1697. // right sizing routine.
  1698. //
  1699. if ( pFormat[1] != FC_PAD )
  1700. {
  1701. SIMPLE_TYPE_BUF_INCREMENT(pStubMsg->BufferLength, pFormat[1]);
  1702. }
  1703. else
  1704. {
  1705. pFormat += 6;
  1706. CORRELATION_DESC_INCREMENT( pFormat );
  1707. pFormat += *((signed short *)pFormat);
  1708. (*pfnSizeRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  1709. pMemory,
  1710. pFormat );
  1711. }
  1712. }
  1713. void RPC_ENTRY
  1714. NdrXmitOrRepAsBufferSize(
  1715. PMIDL_STUB_MESSAGE pStubMsg,
  1716. uchar * pMemory,
  1717. PFORMAT_STRING pFormat )
  1718. /*++
  1719. Routine Description :
  1720. Computes the buffer size needed for a transmit as or represent as object.
  1721. See mrshl.c for the description of the FC layout.
  1722. Arguments :
  1723. pStubMsg - Pointer to the stub message.
  1724. pMemory - Pointer to the transmit/represent as object being sized.
  1725. pFormat - Object's format string description.
  1726. Return :
  1727. None.
  1728. --*/
  1729. {
  1730. const XMIT_ROUTINE_QUINTUPLE * pQuintuple;
  1731. unsigned short QIndex, XmitTypeSize;
  1732. BOOL fXmitByPtr = *pFormat == FC_TRANSMIT_AS_PTR ||
  1733. *pFormat == FC_REPRESENT_AS_PTR;
  1734. // Fetch the QuintupleIndex.
  1735. QIndex = *(unsigned short *)(pFormat + 2);
  1736. // We size the transmitted object, of course.
  1737. pFormat += 6;
  1738. XmitTypeSize = *((unsigned short *)pFormat);
  1739. pQuintuple = pStubMsg->StubDesc->aXmitQuintuple;
  1740. if ( XmitTypeSize )
  1741. {
  1742. // lower nibble of the flag word has the alignment
  1743. unsigned long Align = LOW_NIBBLE(*(pFormat - 5));
  1744. LENGTH_ALIGN( pStubMsg->BufferLength, Align );
  1745. pStubMsg->BufferLength += XmitTypeSize;
  1746. }
  1747. else
  1748. {
  1749. // We have to create an object to size it.
  1750. unsigned char * pTransmittedType;
  1751. // First translate the presented type into the transmitted type.
  1752. // This includes an allocation of a transmitted type object.
  1753. pStubMsg->pPresentedType = pMemory;
  1754. pStubMsg->pTransmitType = NULL;
  1755. pQuintuple[ QIndex ].pfnTranslateToXmit( pStubMsg );
  1756. // bufsize the transmitted type.
  1757. pFormat += 2;
  1758. pFormat = pFormat + *(short *)pFormat;
  1759. pTransmittedType = pStubMsg->pTransmitType;
  1760. // If transmitted type is a pointer, dereference it.
  1761. {
  1762. // Set the current queue to NULL so that all the embedded
  1763. // pointers in the transmitted type will be sized together
  1764. uchar *PointerBufferMarkSave = pStubMsg->PointerBufferMark;
  1765. pStubMsg->PointerBufferMark = 0;
  1766. NDR_POINTER_QUEUE *pOldQueue = NULL;
  1767. if ( pStubMsg->pPointerQueueState )
  1768. {
  1769. pOldQueue = pStubMsg->pPointerQueueState->GetActiveQueue();
  1770. pStubMsg->pPointerQueueState->SetActiveQueue(NULL);
  1771. }
  1772. RpcTryFinally
  1773. {
  1774. (*pfnSizeRoutines[ ROUTINE_INDEX(*pFormat) ])
  1775. ( pStubMsg,
  1776. fXmitByPtr ? *(uchar **)pTransmittedType
  1777. : pTransmittedType,
  1778. pFormat );
  1779. }
  1780. RpcFinally
  1781. {
  1782. pStubMsg->PointerBufferMark = PointerBufferMarkSave;
  1783. if ( pStubMsg->pPointerQueueState )
  1784. {
  1785. pStubMsg->pPointerQueueState->SetActiveQueue(pOldQueue);
  1786. }
  1787. }
  1788. RpcEndFinally
  1789. }
  1790. pStubMsg->pTransmitType = pTransmittedType;
  1791. // Free the temporary transmitted object (it was alloc'ed by the user).
  1792. pQuintuple[ QIndex ].pfnFreeXmit( pStubMsg );
  1793. }
  1794. }
  1795. void
  1796. NdrpUserMarshalBufferSize(
  1797. PMIDL_STUB_MESSAGE pStubMsg,
  1798. uchar * pMemory,
  1799. PFORMAT_STRING pFormat )
  1800. /*++
  1801. Routine Description :
  1802. Computes the buffer size needed for a usr_marshall object.
  1803. See mrshl.c for the description of the FC layout and wire layout.
  1804. Arguments :
  1805. pStubMsg - Pointer to the stub message.
  1806. pMemory - Pointer to the usr_marshall object to buffer size.
  1807. pFormat - Object's format string description.
  1808. Return :
  1809. None.
  1810. --*/
  1811. {
  1812. const USER_MARSHAL_ROUTINE_QUADRUPLE * pQuadruple;
  1813. unsigned short QIndex;
  1814. unsigned long UserOffset;
  1815. USER_MARSHAL_CB UserMarshalCB;
  1816. if ( pFormat[1] & USER_MARSHAL_POINTER )
  1817. {
  1818. // This is an overestimate to correct the size generated
  1819. // by MIDL's state machine for sizing arguments.
  1820. // The maximum alignment gap VARIANT might consume is 11:
  1821. // 4 for the leading pad between unique pointer and wireVARIANT,
  1822. // and 7 bytes if variant is a BSTR, and following parameter is
  1823. // a CY (stuff that's aligned to 8).
  1824. // MZ: Since were overcompensating here, just make this something
  1825. // reasonable like 0x10 which is probably a good max alignment.
  1826. pStubMsg->BufferLength += 0x10;
  1827. }
  1828. // We are here to size a flat object or a pointee object.
  1829. // Optimization: if we know the wire size, don't call the user to size it.
  1830. if ( *(unsigned short *)(pFormat + 6) != 0 )
  1831. {
  1832. pStubMsg->BufferLength += *(unsigned short *)(pFormat + 6);
  1833. }
  1834. else
  1835. {
  1836. // Unknown wire size: Call the user to size his stuff.
  1837. NdrpInitUserMarshalCB( pStubMsg,
  1838. pFormat,
  1839. USER_MARSHAL_CB_BUFFER_SIZE,
  1840. & UserMarshalCB);
  1841. UserOffset = pStubMsg->BufferLength;
  1842. QIndex = *(unsigned short *)(pFormat + 2);
  1843. pQuadruple = pStubMsg->StubDesc->aUserMarshalQuadruple;
  1844. UserOffset = pQuadruple[ QIndex ].pfnBufferSize( (ulong*) &UserMarshalCB,
  1845. UserOffset,
  1846. pMemory );
  1847. pStubMsg->BufferLength = UserOffset;
  1848. }
  1849. }
  1850. void
  1851. NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT::Dispatch(MIDL_STUB_MESSAGE *pStubMsg)
  1852. {
  1853. NdrpUserMarshalBufferSize( pStubMsg,
  1854. pMemory,
  1855. pFormat );
  1856. }
  1857. #if defined(DBG)
  1858. void
  1859. NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT::Print()
  1860. {
  1861. DbgPrint("NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT\n");
  1862. DbgPrint("pMemory: %p\n", pMemory );
  1863. DbgPrint("pFormat: %p\n", pFormat );
  1864. }
  1865. #endif
  1866. void RPC_ENTRY
  1867. NdrUserMarshalBufferSize(
  1868. PMIDL_STUB_MESSAGE pStubMsg,
  1869. uchar * pMemory,
  1870. PFORMAT_STRING pFormat )
  1871. {
  1872. // Check if the object is embedded.
  1873. // Pointer buffer mark is set only when in a complex struct or array.
  1874. // For unions, when the union is embedded in a complex struct or array.
  1875. // If the union is top level, it's the same like a top level object.
  1876. // For unique pointers we don't have to check embedding, we always add 4.
  1877. // For ref pointer we need to check embedding.
  1878. // Align for the flat object or a pointer to the user object.
  1879. LENGTH_ALIGN( pStubMsg->BufferLength, LOW_NIBBLE(pFormat[1]) );
  1880. if ( pFormat[1] & USER_MARSHAL_POINTER )
  1881. {
  1882. if ( (pFormat[1] & USER_MARSHAL_UNIQUE) ||
  1883. ((pFormat[1] & USER_MARSHAL_REF) && pStubMsg->PointerBufferMark) )
  1884. {
  1885. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  1886. }
  1887. if ( pStubMsg->IgnoreEmbeddedPointers )
  1888. return;
  1889. POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext( pStubMsg );
  1890. if ( !pStubMsg->pPointerQueueState ||
  1891. !pStubMsg->pPointerQueueState->GetActiveQueue() )
  1892. {
  1893. NdrpUserMarshalBufferSize(
  1894. pStubMsg,
  1895. pMemory,
  1896. pFormat );
  1897. }
  1898. else
  1899. {
  1900. NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT*pElement =
  1901. new(pStubMsg->pPointerQueueState)
  1902. NDR_USR_MRSHL_BUFSIZE_POINTER_QUEUE_ELEMENT(pMemory,
  1903. pFormat);
  1904. pStubMsg->pPointerQueueState->GetActiveQueue()->Enque( pElement );
  1905. }
  1906. return;
  1907. }
  1908. NdrpUserMarshalBufferSize( pStubMsg,
  1909. pMemory,
  1910. pFormat );
  1911. }
  1912. void
  1913. NdrpInterfacePointerBufferSize (
  1914. PMIDL_STUB_MESSAGE pStubMsg,
  1915. uchar * pMemory,
  1916. PFORMAT_STRING pFormat )
  1917. /*++
  1918. Routine Description :
  1919. Computes the buffer size needed for an interface pointer.
  1920. Arguments :
  1921. pStubMsg - Pointer to the stub message.
  1922. pMemory - The interface pointer being sized.
  1923. pFormat - Interface pointer's format string description.
  1924. Return :
  1925. None.
  1926. --*/
  1927. {
  1928. IID iid;
  1929. IID *piid;
  1930. unsigned long size = 0;
  1931. HRESULT hr;
  1932. //
  1933. // Get an IID pointer.
  1934. //
  1935. if ( pFormat[1] != FC_CONSTANT_IID )
  1936. {
  1937. //
  1938. // We do it same way as we compute variance with a long.
  1939. //
  1940. piid = (IID *) NdrpComputeIIDPointer( pStubMsg,
  1941. pMemory,
  1942. pFormat );
  1943. if(piid == 0)
  1944. RpcRaiseException( RPC_S_INVALID_ARG );
  1945. }
  1946. else
  1947. {
  1948. //
  1949. // The IID may not be aligned properly in the format string,
  1950. // so we copy it to a local variable.
  1951. //
  1952. piid = &iid;
  1953. RpcpMemoryCopy( &iid, &pFormat[2], sizeof(iid) );
  1954. }
  1955. // Allocate space for the length and array bounds.
  1956. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1957. pStubMsg->BufferLength += sizeof(unsigned long) + sizeof(unsigned long);
  1958. hr = (*pfnCoGetMarshalSizeMax)(&size, *piid, (IUnknown *)pMemory, pStubMsg->dwDestContext, pStubMsg->pvDestContext, 0);
  1959. if(FAILED(hr))
  1960. {
  1961. RpcRaiseException(hr);
  1962. }
  1963. pStubMsg->BufferLength += size;
  1964. }
  1965. void RPC_ENTRY
  1966. NdrInterfacePointerBufferSize (
  1967. PMIDL_STUB_MESSAGE pStubMsg,
  1968. uchar * pMemory,
  1969. PFORMAT_STRING pFormat )
  1970. {
  1971. // This function is called only for toplevel interface pointers and
  1972. // backward compatibity
  1973. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  1974. pStubMsg->BufferLength += PTR_WIRE_SIZE;
  1975. if ( pStubMsg->IgnoreEmbeddedPointers )
  1976. return;
  1977. // If the pointer is null, we counted everything.
  1978. if ( pMemory == 0 )
  1979. return;
  1980. NdrpInterfacePointerBufferSize( pStubMsg,
  1981. pMemory,
  1982. pFormat );
  1983. }
  1984. void
  1985. NdrpEmbeddedPointerBufferSize (
  1986. PMIDL_STUB_MESSAGE pStubMsg,
  1987. uchar * pMemory,
  1988. PFORMAT_STRING pFormat )
  1989. /*++
  1990. Routine Description :
  1991. Private routine for computing the buffer size needed for a structure's
  1992. or array's embedded pointers.
  1993. Arguments :
  1994. pStubMsg - Pointer to the stub message.
  1995. pMemory - Pointer to the embedding structure or array.
  1996. pFormat - Format string pointer layout description.
  1997. Return :
  1998. None.
  1999. --*/
  2000. {
  2001. if ( pStubMsg->IgnoreEmbeddedPointers )
  2002. return;
  2003. POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext( pStubMsg );
  2004. void ** ppMemPtr;
  2005. uchar * pMemorySave;
  2006. ULONG_PTR MaxCountSave;
  2007. long OffsetSave;
  2008. MaxCountSave = pStubMsg->MaxCount;
  2009. OffsetSave = pStubMsg->Offset;
  2010. pMemorySave = pStubMsg->Memory;
  2011. // Set new memory context.
  2012. pStubMsg->Memory = pMemory;
  2013. //
  2014. // Increment past the FC_PP and pad.
  2015. //
  2016. pFormat += 2;
  2017. for (;;)
  2018. {
  2019. if ( *pFormat == FC_END )
  2020. {
  2021. pStubMsg->Memory = pMemorySave;
  2022. break;
  2023. }
  2024. //
  2025. // Check for FC_FIXED_REPEAT or FC_VARIABLE_REPEAT.
  2026. //
  2027. if ( *pFormat != FC_NO_REPEAT )
  2028. {
  2029. pStubMsg->MaxCount = MaxCountSave;
  2030. pStubMsg->Offset = OffsetSave;
  2031. NdrpEmbeddedRepeatPointerBufferSize( pStubMsg,
  2032. pMemory,
  2033. &pFormat );
  2034. // Continue to the next pointer.
  2035. continue;
  2036. }
  2037. // Compute the pointer to the pointer in memory to size.
  2038. ppMemPtr = (void **) (pMemory + *((signed short *)(pFormat + 2)));
  2039. // Increment to the pointer description.
  2040. pFormat += 6;
  2041. NdrpPointerBufferSize(
  2042. pStubMsg,
  2043. (uchar*)*ppMemPtr,
  2044. pFormat );
  2045. // Increment past pointer description.
  2046. pFormat += 4;
  2047. }
  2048. }
  2049. void
  2050. NdrpEmbeddedRepeatPointerBufferSize (
  2051. PMIDL_STUB_MESSAGE pStubMsg,
  2052. uchar * pMemory,
  2053. PFORMAT_STRING * ppFormat )
  2054. /*++
  2055. Routine Description :
  2056. Private routine for computing the buffer size needed for an array's
  2057. embedded pointers.
  2058. Arguments :
  2059. pStubMsg - Pointer to the stub message.
  2060. pMemory - Pointer to the embedding array.
  2061. pFormat - The array's format string pointer layout description.
  2062. Return :
  2063. None.
  2064. --*/
  2065. {
  2066. uchar ** ppMemPtr;
  2067. PFORMAT_STRING pFormat;
  2068. PFORMAT_STRING pFormatSave;
  2069. uchar * pMemorySave;
  2070. ulong RepeatCount,RepeatIncrement, Pointers, PointersSave;
  2071. pMemorySave = pStubMsg->Memory;
  2072. // Get current format string pointer.
  2073. pFormat = *ppFormat;
  2074. switch ( *pFormat )
  2075. {
  2076. case FC_FIXED_REPEAT :
  2077. // Increment past the FC_FIXED_REPEAT and FC_PAD.
  2078. pFormat += 2;
  2079. // Get the total number of times to repeat the pointer marshall.
  2080. RepeatCount = *((ushort *&)pFormat)++;
  2081. break;
  2082. case FC_VARIABLE_REPEAT :
  2083. // Get the total number of times to repeat the pointer marshall.
  2084. RepeatCount = (ulong)pStubMsg->MaxCount;
  2085. //
  2086. // Check if this variable repeat instance also has a variable
  2087. // offset (this would be the case for a conformant varying array
  2088. // of pointers). If so then increment the memory pointer to point
  2089. // to the actual first array element which is being marshalled.
  2090. //
  2091. if ( pFormat[1] == FC_VARIABLE_OFFSET )
  2092. pMemory += *((ushort *)(pFormat + 2)) * pStubMsg->Offset;
  2093. // else pFormat[1] == FC_FIXED_OFFSET - do nothing
  2094. // Increment past the FC_VARIABLE_REPEAT and FC_PAD.
  2095. pFormat += 2;
  2096. break;
  2097. default :
  2098. NDR_ASSERT(0,"NdrpEmbeddedRepeatPointerMarshall : bad format char");
  2099. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  2100. return;
  2101. }
  2102. // Get the increment amount between successive pointers.
  2103. RepeatIncrement = *((ushort *&)pFormat)++;
  2104. //
  2105. // Add the offset to the beginning of this array to the Memory
  2106. // pointer. This is the offset from any currently embedding structure
  2107. // to the array whose pointers we're marshalling.
  2108. //
  2109. pStubMsg->Memory += *((ushort *&)pFormat)++;
  2110. // Get the number of pointers in this repeat instance.
  2111. PointersSave = Pointers = *((ushort *&)pFormat)++;
  2112. pFormatSave = pFormat;
  2113. //
  2114. // Loop over the number of elements in the array.
  2115. //
  2116. for ( ; RepeatCount--;
  2117. pMemory += RepeatIncrement,
  2118. pStubMsg->Memory += RepeatIncrement )
  2119. {
  2120. pFormat = pFormatSave;
  2121. Pointers = PointersSave;
  2122. //
  2123. // Loop over the number of pointers in each array element (this can
  2124. // be greater than one if we have an array of structures).
  2125. //
  2126. for ( ; Pointers--; )
  2127. {
  2128. // Pointer to the pointer in memory.
  2129. ppMemPtr = (uchar **)(pMemory + *((signed short *)pFormat));
  2130. // Increment to pointer description.
  2131. pFormat += 4;
  2132. NdrpPointerBufferSize(
  2133. pStubMsg,
  2134. (uchar*)*ppMemPtr,
  2135. pFormat );
  2136. // Increment to the next pointer description.
  2137. pFormat += 4;
  2138. }
  2139. }
  2140. // Update format string pointer past this repeat pointer description.
  2141. *ppFormat = pFormatSave + PointersSave * 8;
  2142. pStubMsg->Memory = pMemorySave;
  2143. }
  2144. void RPC_ENTRY
  2145. NdrContextHandleSize(
  2146. PMIDL_STUB_MESSAGE pStubMsg,
  2147. uchar * pMemory,
  2148. PFORMAT_STRING pFormat )
  2149. /*++
  2150. Routine Description :
  2151. Computes the buffer size needed for a context handle.
  2152. Arguments :
  2153. pStubMsg - Pointer to the stub message.
  2154. pMemory - Ignored.
  2155. pFormat - Ignored.
  2156. Return :
  2157. None.
  2158. --*/
  2159. {
  2160. LENGTH_ALIGN(pStubMsg->BufferLength,0x3);
  2161. pStubMsg->BufferLength += CONTEXT_HANDLE_WIRE_SIZE;
  2162. }
  2163. #ifdef _CS_CHAR_
  2164. void RPC_ENTRY
  2165. NdrCsTagBufferSize(
  2166. PMIDL_STUB_MESSAGE pStubMsg,
  2167. uchar * pMemory,
  2168. PFORMAT_STRING pFormat )
  2169. /*++
  2170. Routine Description :
  2171. Computes the buffer size needed for a cs tag param. Also copies the
  2172. sending tag value to the stub message for use by NdrCsArrayXXX.
  2173. Arguments :
  2174. pStubMsg - Pointer to the stub message.
  2175. pMemory - Pointer to the embedding array.
  2176. pFormat - Pointer to the FC_CSTAG entry in the format string.
  2177. Return :
  2178. None.
  2179. --*/
  2180. {
  2181. // We need to set the tag in the stub message so that we can properly
  2182. // size subsequent cs_char arrays.
  2183. NdrpGetSetCSTagMarshall( pStubMsg, pMemory, (NDR_CS_TAG_FORMAT *) pFormat);
  2184. LENGTH_ALIGN( pStubMsg->BufferLength, 3 );
  2185. pStubMsg->BufferLength += sizeof( unsigned long );
  2186. }
  2187. void RPC_ENTRY
  2188. NdrCsArrayBufferSize(
  2189. PMIDL_STUB_MESSAGE pStubMsg,
  2190. uchar * pMemory,
  2191. PFORMAT_STRING pFormat )
  2192. /*++
  2193. Routine Description :
  2194. Computes the buffer size needed for a cs_char array
  2195. Arguments :
  2196. pStubMsg - Pointer to the stub message.
  2197. pMemory - Pointer to the embedding array.
  2198. pFormat - Pointer to the FC_CSARRAY entry in the format string.
  2199. Return :
  2200. None.
  2201. --*/
  2202. {
  2203. NDR_CS_ARRAY_FORMAT *pCSFormat = (NDR_CS_ARRAY_FORMAT *) pFormat;
  2204. ulong Size;
  2205. ulong Length;
  2206. ulong WireSize;
  2207. NDR_ASSERT( NULL != pStubMsg->pCSInfo, "cs_char stub info not set up");
  2208. // Skip pFormat to the underlying array descriptor
  2209. pFormat += pCSFormat->DescriptionOffset;
  2210. // Leave room for the max count / offset / actual count
  2211. if ( NdrpIsVaryingArray( pFormat ) )
  2212. {
  2213. LENGTH_ALIGN( pStubMsg->BufferLength, 3 );
  2214. pStubMsg->BufferLength += 8;
  2215. }
  2216. if ( NdrpIsConformantArray( pFormat ) )
  2217. {
  2218. LENGTH_ALIGN( pStubMsg->BufferLength, 3 );
  2219. pStubMsg->BufferLength += 4;
  2220. }
  2221. // Get the base size and length
  2222. NdrpGetArraySizeLength (
  2223. pStubMsg,
  2224. pMemory,
  2225. pFormat,
  2226. 1,
  2227. (long*)&Size,
  2228. (long*)&Length,
  2229. (long*)&WireSize );
  2230. // Call XXX_net_size to estimate the buffer space required to store this
  2231. // array after conversion. For fixed or varying arrays the buffer
  2232. // space is equal to the fixed upper bound specified in the idl file.
  2233. if ( !NdrpIsVaryingArray( pFormat ) )
  2234. {
  2235. NDR_CS_SIZE_CONVERT_ROUTINES *CSRoutines;
  2236. CS_TYPE_NET_SIZE_ROUTINE SizingRoutine;
  2237. IDL_CS_CONVERT ConversionType;
  2238. error_status_t Status;
  2239. CSRoutines = pStubMsg->StubDesc->CsRoutineTables->pSizeConvertRoutines;
  2240. SizingRoutine = CSRoutines[ pCSFormat->CSRoutineIndex ].pfnNetSize;
  2241. SizingRoutine(
  2242. NULL,
  2243. pStubMsg->pCSInfo->WireCodeset,
  2244. Size,
  2245. (IDL_CS_CONVERT*)&ConversionType,
  2246. &Size,
  2247. &Status);
  2248. if (RPC_S_OK != Status)
  2249. RpcRaiseException(Status);
  2250. }
  2251. pStubMsg->BufferLength += Size;
  2252. }
  2253. #endif // _CS_CHAR_
  2254. void
  2255. NdrPartialIgnoreClientBufferSize(
  2256. PMIDL_STUB_MESSAGE pStubMsg,
  2257. void * pMemory
  2258. )
  2259. {
  2260. LENGTH_ALIGN( pStubMsg->BufferLength, 0x3 );
  2261. pStubMsg->Buffer += PTR_WIRE_SIZE;
  2262. }