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.

3821 lines
107 KiB

  1. /************************************************************************
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name :
  4. mrshl.c
  5. Abstract :
  6. This file contains the marshalling routines called by MIDL generated
  7. stubs and the interpreter.
  8. Author :
  9. David Kays dkays September 1993.
  10. Revision History :
  11. ***********************************************************************/
  12. #include "ndrp.h"
  13. #include "hndl.h"
  14. #include "ndrole.h"
  15. #include "attack.h"
  16. #include "pointerq.h"
  17. unsigned char *RPC_ENTRY
  18. NdrUDTSimpleTypeMarshall1(
  19. PMIDL_STUB_MESSAGE pStubMsg,
  20. unsigned char * pMemory,
  21. PFORMAT_STRING pFormat
  22. );
  23. //
  24. // Function table of marshalling routines.
  25. //
  26. extern const PMARSHALL_ROUTINE MarshallRoutinesTable[] =
  27. {
  28. NdrUDTSimpleTypeMarshall1,
  29. NdrUDTSimpleTypeMarshall1,
  30. NdrUDTSimpleTypeMarshall1,
  31. NdrUDTSimpleTypeMarshall1,
  32. NdrUDTSimpleTypeMarshall1,
  33. NdrUDTSimpleTypeMarshall1,
  34. NdrUDTSimpleTypeMarshall1,
  35. NdrUDTSimpleTypeMarshall1,
  36. NdrUDTSimpleTypeMarshall1,
  37. NdrUDTSimpleTypeMarshall1,
  38. NdrUDTSimpleTypeMarshall1,
  39. NdrUDTSimpleTypeMarshall1,
  40. NdrUDTSimpleTypeMarshall1,
  41. NdrUDTSimpleTypeMarshall1,
  42. NdrUDTSimpleTypeMarshall1,
  43. NdrUDTSimpleTypeMarshall1,
  44. NdrUDTSimpleTypeMarshall1,
  45. NdrPointerMarshall,
  46. NdrPointerMarshall,
  47. NdrPointerMarshall,
  48. NdrPointerMarshall,
  49. NdrSimpleStructMarshall,
  50. NdrSimpleStructMarshall,
  51. NdrConformantStructMarshall,
  52. NdrConformantStructMarshall,
  53. NdrConformantVaryingStructMarshall,
  54. NdrComplexStructMarshall,
  55. NdrConformantArrayMarshall,
  56. NdrConformantVaryingArrayMarshall,
  57. NdrFixedArrayMarshall,
  58. NdrFixedArrayMarshall,
  59. NdrVaryingArrayMarshall,
  60. NdrVaryingArrayMarshall,
  61. NdrComplexArrayMarshall,
  62. NdrConformantStringMarshall,
  63. NdrConformantStringMarshall,
  64. NdrConformantStringMarshall,
  65. NdrConformantStringMarshall,
  66. NdrNonConformantStringMarshall,
  67. NdrNonConformantStringMarshall,
  68. NdrNonConformantStringMarshall,
  69. NdrNonConformantStringMarshall,
  70. NdrEncapsulatedUnionMarshall,
  71. NdrNonEncapsulatedUnionMarshall,
  72. NdrByteCountPointerMarshall,
  73. NdrXmitOrRepAsMarshall, // transmit as
  74. NdrXmitOrRepAsMarshall, // represent as
  75. NdrPointerMarshall,
  76. NdrMarshallHandle,
  77. // New Post NT 3.5 token serviced from here on.
  78. 0, // NdrHardStructMarshall,
  79. NdrXmitOrRepAsMarshall, // transmit as ptr
  80. NdrXmitOrRepAsMarshall, // represent as ptr
  81. NdrUserMarshalMarshall,
  82. 0, // FC_PIPE
  83. 0, // FC_BLK_HOLE
  84. NdrpRangeMarshall,
  85. 0, // FC_INT3264
  86. 0, // FC_UINT3264
  87. 0, // NdrCsArrayMarshall,
  88. 0, // NdrCsTagMarshall
  89. };
  90. extern const PMARSHALL_ROUTINE * pfnMarshallRoutines = MarshallRoutinesTable;
  91. unsigned char *
  92. NdrpInterfacePointerMarshall (
  93. PMIDL_STUB_MESSAGE pStubMsg,
  94. uchar * pMemory,
  95. PFORMAT_STRING pFormat );
  96. RPCRTAPI
  97. unsigned char *RPC_ENTRY
  98. NdrTypeMarshall(
  99. PMIDL_STUB_MESSAGE pStubMsg,
  100. uchar * pMemory,
  101. PFORMAT_STRING pFormat )
  102. {
  103. return
  104. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  105. pMemory,
  106. pFormat );
  107. }
  108. __inline unsigned char *RPC_ENTRY
  109. NdrUDTSimpleTypeMarshall1(
  110. PMIDL_STUB_MESSAGE pStubMsg,
  111. uchar * pMemory,
  112. PFORMAT_STRING FormatString )
  113. {
  114. NdrSimpleTypeMarshall(pStubMsg,pMemory,*FormatString);
  115. return 0;
  116. }
  117. void __fastcall NdrpSimpleTypeCharMarshall (
  118. PMIDL_STUB_MESSAGE pStubMsg,
  119. uchar * pMemory)
  120. {
  121. ZEROOUT_GAP( pStubMsg->Buffer );
  122. *(pStubMsg->Buffer)++ = *pMemory;
  123. }
  124. void __fastcall NdrpSimpleTypeShortMarshall (
  125. PMIDL_STUB_MESSAGE pStubMsg,
  126. uchar * pMemory)
  127. {
  128. ZEROOUT_GAP( pStubMsg->Buffer );
  129. ALIGN(pStubMsg->Buffer,1);
  130. *((ushort *&)pStubMsg->Buffer)++ = *((ushort *)pMemory);
  131. }
  132. void __fastcall NdrpSimpleTypeLongMarshall (
  133. PMIDL_STUB_MESSAGE pStubMsg,
  134. uchar * pMemory)
  135. {
  136. ZEROOUT_GAP( pStubMsg->Buffer );
  137. ALIGN(pStubMsg->Buffer,3);
  138. *((ulong *&)pStubMsg->Buffer)++ = *((ulong *)pMemory);
  139. }
  140. void __fastcall NdrpSimpleTypeHyperMarshall (
  141. PMIDL_STUB_MESSAGE pStubMsg,
  142. uchar * pMemory)
  143. {
  144. ZEROOUT_GAP( pStubMsg->Buffer );
  145. ZeroOutGapAndAlign( pStubMsg , 7) ;
  146. //
  147. // Let's stay away from casts to double.
  148. //
  149. *((ulong *&)pStubMsg->Buffer)++ = *((ulong *)pMemory);
  150. *((ulong *&)pStubMsg->Buffer)++ = *((ulong *)(pMemory + 4));
  151. }
  152. void __fastcall NdrpSimpleTypeEnum16Marshall (
  153. PMIDL_STUB_MESSAGE pStubMsg,
  154. uchar * pMemory)
  155. {
  156. if ( *((int *)pMemory) & ~((int)0x7fff) )
  157. {
  158. RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  159. }
  160. ZEROOUT_GAP( pStubMsg->Buffer );
  161. ALIGN(pStubMsg->Buffer,1);
  162. *((ushort *&)pStubMsg->Buffer)++ = *((ushort *)pMemory);
  163. }
  164. void __fastcall NdrpSimpleTypeIgnoreMarshall (
  165. PMIDL_STUB_MESSAGE ,
  166. uchar * )
  167. {
  168. }
  169. void __fastcall NdrpSimpleTypeInvalidMarshall (
  170. PMIDL_STUB_MESSAGE ,
  171. uchar * )
  172. {
  173. NDR_ASSERT(0,"NdrSimpleTypeMarshall : bad format char");
  174. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  175. }
  176. // make this extern as this will be call from ClientMarshal & ServerMarshal also.
  177. extern const PSIMPLETYPE_MARSHAL_ROUTINE SimpleTypeMarshallRoutinesTable[] =
  178. {
  179. NdrpSimpleTypeInvalidMarshall,
  180. NdrpSimpleTypeCharMarshall,
  181. NdrpSimpleTypeCharMarshall,
  182. NdrpSimpleTypeCharMarshall,
  183. NdrpSimpleTypeCharMarshall,
  184. NdrpSimpleTypeShortMarshall,
  185. NdrpSimpleTypeShortMarshall,
  186. NdrpSimpleTypeShortMarshall,
  187. NdrpSimpleTypeLongMarshall,
  188. NdrpSimpleTypeLongMarshall,
  189. NdrpSimpleTypeLongMarshall, // FC_FLOAT
  190. NdrpSimpleTypeHyperMarshall,
  191. NdrpSimpleTypeHyperMarshall,
  192. NdrpSimpleTypeEnum16Marshall, // FC_ENUM16
  193. NdrpSimpleTypeLongMarshall,
  194. NdrpSimpleTypeIgnoreMarshall,
  195. NdrpSimpleTypeLongMarshall, // fc_error_status_t
  196. NdrpSimpleTypeInvalidMarshall,
  197. NdrpSimpleTypeInvalidMarshall,
  198. NdrpSimpleTypeInvalidMarshall,
  199. NdrpSimpleTypeInvalidMarshall,
  200. NdrpSimpleTypeInvalidMarshall,
  201. NdrpSimpleTypeInvalidMarshall,
  202. NdrpSimpleTypeInvalidMarshall,
  203. NdrpSimpleTypeInvalidMarshall,
  204. NdrpSimpleTypeInvalidMarshall,
  205. NdrpSimpleTypeInvalidMarshall,
  206. NdrpSimpleTypeInvalidMarshall,
  207. NdrpSimpleTypeInvalidMarshall,
  208. NdrpSimpleTypeInvalidMarshall,
  209. NdrpSimpleTypeInvalidMarshall,
  210. NdrpSimpleTypeInvalidMarshall,
  211. NdrpSimpleTypeInvalidMarshall,
  212. NdrpSimpleTypeInvalidMarshall,
  213. NdrpSimpleTypeInvalidMarshall,
  214. NdrpSimpleTypeInvalidMarshall,
  215. NdrpSimpleTypeInvalidMarshall,
  216. NdrpSimpleTypeInvalidMarshall,
  217. NdrpSimpleTypeInvalidMarshall,
  218. NdrpSimpleTypeInvalidMarshall,
  219. NdrpSimpleTypeInvalidMarshall,
  220. NdrpSimpleTypeInvalidMarshall,
  221. NdrpSimpleTypeInvalidMarshall,
  222. NdrpSimpleTypeInvalidMarshall,
  223. NdrpSimpleTypeInvalidMarshall,
  224. NdrpSimpleTypeInvalidMarshall, // transmit as
  225. NdrpSimpleTypeInvalidMarshall, // represent as
  226. NdrpSimpleTypeInvalidMarshall,
  227. NdrpSimpleTypeInvalidMarshall,
  228. // New Post NT 3.5 token serviced from here on.
  229. NdrpSimpleTypeInvalidMarshall, // NdrHardStructMarshall,
  230. NdrpSimpleTypeInvalidMarshall, // transmit as ptr
  231. NdrpSimpleTypeInvalidMarshall, // represent as ptr
  232. NdrpSimpleTypeInvalidMarshall,
  233. NdrpSimpleTypeInvalidMarshall, // FC_PIPE
  234. NdrpSimpleTypeInvalidMarshall, // FC_BLK_HOLE
  235. NdrpSimpleTypeInvalidMarshall,
  236. #if defined(__RPC_WIN64__)
  237. NdrpSimpleTypeLongMarshall, // FC_INT3264
  238. NdrpSimpleTypeLongMarshall, // FC_UINT3264
  239. #else
  240. NdrpSimpleTypeInvalidMarshall,
  241. NdrpSimpleTypeInvalidMarshall,
  242. #endif
  243. NdrpSimpleTypeInvalidMarshall, // NdrCsArrayMarshall,
  244. NdrpSimpleTypeInvalidMarshall, // NdrCsTagMarshall
  245. };
  246. void RPC_ENTRY
  247. NdrSimpleTypeMarshall(
  248. PMIDL_STUB_MESSAGE pStubMsg,
  249. uchar * pMemory,
  250. uchar FormatChar )
  251. /*++
  252. Routine Description :
  253. Marshalls a simple type.
  254. Arguments :
  255. pStubMsg - Pointer to the stub message.
  256. pMemory - Pointer to the data to be marshalled.
  257. FormatChar - Simple type format character.
  258. Return :
  259. None.
  260. --*/
  261. {
  262. SimpleTypeMarshallRoutinesTable[ROUTINE_INDEX(FormatChar)](pStubMsg, pMemory );
  263. }
  264. unsigned char * RPC_ENTRY
  265. NdrpRangeMarshall(
  266. PMIDL_STUB_MESSAGE pStubMsg,
  267. uchar * pMemory,
  268. PFORMAT_STRING pFormat )
  269. /*++
  270. --*/
  271. {
  272. uchar FcType = pFormat[1] & 0x0f;
  273. NdrSimpleTypeMarshall( pStubMsg, pMemory, FcType );
  274. return 0;
  275. }
  276. unsigned char * RPC_ENTRY
  277. NdrPointerMarshall(
  278. PMIDL_STUB_MESSAGE pStubMsg,
  279. uchar * pMemory,
  280. PFORMAT_STRING pFormat )
  281. /*++
  282. Routine Description :
  283. Marshalls a top level pointer to anything. Pointers embedded in
  284. structures, arrays, or unions call NdrpPointerMarshall directly.
  285. Used for FC_RP, FC_UP, FC_FP, FC_OP.
  286. Arguments :
  287. pStubMsg - Pointer to the stub message.
  288. pMemory - Pointer to the data to be marshalled.
  289. pFormat - Pointer's format string description.
  290. Return :
  291. None.
  292. --*/
  293. {
  294. uchar * pBufferMark;
  295. //
  296. // If this is not a ref pointer then set buffer mark and increment the
  297. // stub message buffer pointer.
  298. //
  299. if ( *pFormat != FC_RP )
  300. {
  301. ALIGN( pStubMsg->Buffer, 3 );
  302. // This is where we marshall the node id.
  303. pBufferMark = pStubMsg->Buffer;
  304. pStubMsg->Buffer += PTR_WIRE_SIZE;
  305. }
  306. else
  307. pBufferMark = 0;
  308. //
  309. // For ref pointers pBufferMark will not be used and can be left
  310. // unitialized.
  311. //
  312. NdrpPointerMarshall( pStubMsg,
  313. pBufferMark,
  314. pMemory,
  315. pFormat );
  316. return 0;
  317. }
  318. __forceinline void
  319. NdrpPointerMarshallInternal(
  320. PMIDL_STUB_MESSAGE pStubMsg,
  321. uchar * pBufferMark,
  322. uchar * pMemory,
  323. PFORMAT_STRING pFormat )
  324. /*++
  325. Routine Description :
  326. Private routine for marshalling a pointer and its pointee. This is the
  327. entry point for pointers embedded in structures, arrays, and unions.
  328. Used for FC_RP, FC_UP, FC_FP, FC_OP.
  329. Arguments :
  330. pStubMsg - Pointer to the stub message.
  331. pBufferMark - The location in the buffer where the pointer itself is
  332. marshalled. Important for full pointers, unfortunately it's
  333. overkill for unique pointers.
  334. pMemory - Pointer to the data to be marshalled.
  335. pFormat - Pointer format string description.
  336. pStubMsg->Buffer - the place for the pointee.
  337. Return :
  338. None.
  339. --*/
  340. {
  341. //
  342. // Check the pointer type.
  343. //
  344. switch ( *pFormat )
  345. {
  346. case FC_RP :
  347. if ( ! pMemory )
  348. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  349. break;
  350. case FC_UP :
  351. case FC_OP :
  352. // Put the pointer in the buffer.
  353. *((ulong*&)pBufferMark)++ = PTR_WIRE_REP(pMemory, pStubMsg);
  354. if ( ! pMemory )
  355. return;
  356. break;
  357. case FC_IP :
  358. if ( IS_BROKEN_INTERFACE_POINTER(pStubMsg->uFlags) )
  359. {
  360. // The pointee is effectivly both the pointer
  361. // and the pointee.
  362. NdrInterfacePointerMarshall( pStubMsg,
  363. pMemory,
  364. pFormat );
  365. return;
  366. }
  367. // Interface pointers behave like unique pointers
  368. *((ulong*&)pBufferMark)++ = PTR_WIRE_REP(pMemory, pStubMsg);
  369. if ( ! pMemory )
  370. return;
  371. NdrpInterfacePointerMarshall( pStubMsg,
  372. pMemory,
  373. pFormat );
  374. return;
  375. case FC_FP :
  376. //
  377. // Marshall the pointer's ref id and see if we've already
  378. // marshalled the pointer's data.
  379. //
  380. if ( NdrFullPointerQueryPointer( pStubMsg->FullPtrXlatTables,
  381. pMemory,
  382. FULL_POINTER_MARSHALLED,
  383. (ulong *) pBufferMark ) )
  384. return;
  385. break;
  386. default :
  387. NDR_ASSERT(0,"NdrpPointerMarshall : bad pointer type");
  388. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  389. return;
  390. }
  391. //
  392. // Check for a pointer to a complex type.
  393. //
  394. if ( ! SIMPLE_POINTER(pFormat[1]) )
  395. {
  396. uchar uFlagsSave;
  397. if ( POINTER_DEREF(pFormat[1]) )
  398. pMemory = *((uchar **)pMemory);
  399. // Increment to offset_to_complex_description<2> field.
  400. pFormat += 2;
  401. //
  402. // Set format string to complex type description.
  403. // Cast must be to a signed short since some offsets are negative.
  404. //
  405. pFormat += *((signed short *)pFormat);
  406. //
  407. // Look up the proper marshalling routine in the marshalling function
  408. // table.
  409. //
  410. uFlagsSave = pStubMsg->uFlags;
  411. RESET_CONF_FLAGS_TO_STANDALONE(pStubMsg->uFlags);
  412. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  413. pMemory,
  414. pFormat );
  415. pStubMsg->uFlags = uFlagsSave;
  416. return;
  417. }
  418. //
  419. // Else it's a pointer to a simple type or a string pointer.
  420. //
  421. switch ( pFormat[2] )
  422. {
  423. case FC_C_CSTRING :
  424. case FC_C_BSTRING :
  425. case FC_C_WSTRING :
  426. case FC_C_SSTRING :
  427. NdrConformantStringMarshall( pStubMsg,
  428. pMemory,
  429. pFormat + 2 );
  430. break;
  431. default :
  432. NdrSimpleTypeMarshall( pStubMsg,
  433. pMemory,
  434. pFormat[2] );
  435. break;
  436. }
  437. }
  438. NDR_MRSHL_POINTER_QUEUE_ELEMENT::NDR_MRSHL_POINTER_QUEUE_ELEMENT(
  439. MIDL_STUB_MESSAGE *pStubMsg,
  440. uchar * const pBufferMarkNew,
  441. uchar * const pMemoryNew,
  442. const PFORMAT_STRING pFormatNew) :
  443. pBufferMark(pBufferMarkNew),
  444. pMemory(pMemoryNew),
  445. pFormat(pFormatNew),
  446. Memory(pStubMsg->Memory),
  447. uFlags(pStubMsg->uFlags)
  448. {
  449. }
  450. void
  451. NDR_MRSHL_POINTER_QUEUE_ELEMENT::Dispatch(
  452. MIDL_STUB_MESSAGE *pStubMsg)
  453. {
  454. SAVE_CONTEXT<uchar*> MemorySave( pStubMsg->Memory, Memory );
  455. SAVE_CONTEXT<uchar> uFlagsSave( pStubMsg->uFlags, uFlags );
  456. NDR_ASSERT( !pStubMsg->PointerBufferMark, "PointerBufferMark is not 0\n");
  457. NdrpPointerMarshallInternal( pStubMsg,
  458. pBufferMark,
  459. pMemory,
  460. pFormat );
  461. }
  462. #if defined(DBG)
  463. void
  464. NDR_MRSHL_POINTER_QUEUE_ELEMENT::Print()
  465. {
  466. DbgPrint("NDR_MRSHL_POINTER_QUEUE_ELEMENT\n");
  467. DbgPrint("pNext: %p\n", pNext );
  468. DbgPrint("pBufferMark: %p\n", pBufferMark );
  469. DbgPrint("pMemory: %p\n", pMemory );
  470. DbgPrint("pFormat: %p\n", pFormat );
  471. DbgPrint("Memory: %p\n", Memory );
  472. DbgPrint("uFlags: %x\n", uFlags );
  473. }
  474. #endif
  475. void
  476. NdrpEnquePointerMarshall(
  477. PMIDL_STUB_MESSAGE pStubMsg,
  478. uchar * pBufferMark,
  479. uchar * pMemory,
  480. PFORMAT_STRING pFormat )
  481. {
  482. NDR32_POINTER_CONTEXT PointerContext( pStubMsg );
  483. RpcTryFinally
  484. {
  485. NDR_MRSHL_POINTER_QUEUE_ELEMENT*pElement =
  486. new(PointerContext.GetActiveState())
  487. NDR_MRSHL_POINTER_QUEUE_ELEMENT(pStubMsg,
  488. pBufferMark,
  489. pMemory,
  490. pFormat);
  491. PointerContext.Enque( pElement );
  492. PointerContext.DispatchIfRequired();
  493. }
  494. RpcFinally
  495. {
  496. PointerContext.EndContext();
  497. }
  498. RpcEndFinally
  499. }
  500. void
  501. NdrpPointerMarshall(
  502. PMIDL_STUB_MESSAGE pStubMsg,
  503. uchar * pBufferMark,
  504. uchar * pMemory,
  505. PFORMAT_STRING pFormat )
  506. {
  507. if ( !NdrIsLowStack(pStubMsg) )
  508. {
  509. NdrpPointerMarshallInternal( pStubMsg,
  510. pBufferMark,
  511. pMemory,
  512. pFormat );
  513. return;
  514. }
  515. NdrpEnquePointerMarshall( pStubMsg,
  516. pBufferMark,
  517. pMemory,
  518. pFormat );
  519. }
  520. unsigned char * RPC_ENTRY
  521. NdrSimpleStructMarshall(
  522. PMIDL_STUB_MESSAGE pStubMsg,
  523. uchar * pMemory,
  524. PFORMAT_STRING pFormat )
  525. /*++
  526. Routine description :
  527. Marshalls a simple structure.
  528. Used for FC_STRUCT and FC_PSTRUCT.
  529. Arguments :
  530. pStubMsg - Pointer to the stub message.
  531. pMemory - Pointer to the structure to be marshalled.
  532. pFormat - Structure's format string description.
  533. Return :
  534. None.
  535. --*/
  536. {
  537. uint StructSize;
  538. ZeroOutGapAndAlign(pStubMsg,pFormat[1]);
  539. StructSize = (uint) *((ushort *)(pFormat + 2));
  540. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  541. pMemory,
  542. StructSize );
  543. // Mark the start of the structure in the buffer.
  544. pStubMsg->BufferMark = pStubMsg->Buffer;
  545. pStubMsg->Buffer += StructSize;
  546. // Marshall embedded pointers.
  547. if ( *pFormat == FC_PSTRUCT )
  548. {
  549. NdrpEmbeddedPointerMarshall( pStubMsg,
  550. pMemory,
  551. pFormat + 4 );
  552. }
  553. return 0;
  554. }
  555. unsigned char * RPC_ENTRY
  556. NdrConformantStructMarshall(
  557. PMIDL_STUB_MESSAGE pStubMsg,
  558. uchar * pMemory,
  559. PFORMAT_STRING pFormat )
  560. /*++
  561. Routine description :
  562. Marshalls a conformant structure.
  563. Used for FC_CSTRUCT and FC_CPSTRUCT.
  564. Arguments :
  565. pStubMsg - Pointer to the stub message.
  566. pMemory - Pointer to the structure to be marshalled.
  567. pFormat - Structure's format string description.
  568. Return :
  569. None. - may set the CONF_ARRAY_DONE flag.
  570. Note
  571. Due to problems with MIDL generated code, the ConformantStruct routine always
  572. marshals the conformant array. Only a bogus struct can embed a conf struct,
  573. and there is a flag that bogus struct watches in order not to marshal the array
  574. second time.
  575. --*/
  576. {
  577. PFORMAT_STRING pFormatArray;
  578. uint StructSize;
  579. uchar Alignment;
  580. uchar fIsEmbeddedStruct = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  581. // Save structure's alignment.
  582. Alignment = pFormat[1];
  583. // Increment format string to struct size field.
  584. pFormat += 2;
  585. // Get flat struct size and increment format string.
  586. StructSize = (uint) *((ushort *&)pFormat)++;
  587. // Set conformant array format string description.
  588. pFormatArray = pFormat + *((signed short *)pFormat);
  589. //
  590. // Compute conformance information. Pass a memory pointer to the
  591. // end of the non-conformant part of the structure.
  592. //
  593. NdrpComputeConformance( pStubMsg,
  594. pMemory + StructSize,
  595. pFormatArray );
  596. // Only a bogus struct can embed a conf struct.
  597. if ( fIsEmbeddedStruct )
  598. *(ulong *)pStubMsg->BufferMark = (ulong)pStubMsg->MaxCount;
  599. else
  600. {
  601. // Align the buffer for conformance count marshalling.
  602. ALIGN(pStubMsg->Buffer,3);
  603. // Marshall conformance count.
  604. *((ulong *&)pStubMsg->Buffer)++ = (ulong)pStubMsg->MaxCount;
  605. }
  606. // Re-align buffer
  607. ZeroOutGapAndAlign(pStubMsg,Alignment);
  608. // Increment array format string to array element size field.
  609. pFormatArray += 2;
  610. // Add the size of the conformant array to the structure size.
  611. StructSize += (ulong)pStubMsg->MaxCount * *((ushort *)pFormatArray);
  612. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  613. pMemory,
  614. StructSize );
  615. // Update the buffer pointer.
  616. pStubMsg->Buffer += StructSize;
  617. // Increment format string past offset to array description field.
  618. pFormat += 2;
  619. // Marshall embedded pointers. This covers the struct and the conf array.
  620. if ( *pFormat == FC_PP )
  621. {
  622. // Mark the start of the structure in the buffer.
  623. pStubMsg->BufferMark = pStubMsg->Buffer - StructSize;
  624. NdrpEmbeddedPointerMarshall( pStubMsg,
  625. pMemory,
  626. pFormat );
  627. }
  628. // Only a complex struct may set up this flag for embedding.
  629. // Set the reverse flag to signal that array has been marshaled.
  630. if ( fIsEmbeddedStruct )
  631. SET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  632. return 0;
  633. }
  634. unsigned char * RPC_ENTRY
  635. NdrConformantVaryingStructMarshall(
  636. PMIDL_STUB_MESSAGE pStubMsg,
  637. uchar * pMemory,
  638. PFORMAT_STRING pFormat )
  639. /*++
  640. Routine description :
  641. Marshalls a structure which contains a conformant varying array.
  642. Used for FC_CVSTRUCT.
  643. Arguments :
  644. pStubMsg - Pointer to the stub message.
  645. pMemory - Pointer to the structure to be marshalled.
  646. pFormat - Structure's format string description.
  647. Return :
  648. None.
  649. --*/
  650. {
  651. PFORMAT_STRING pFormatArray;
  652. uint StructSize;
  653. uchar Alignment;
  654. uchar fIsEmbeddedStruct = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  655. uchar* pBuffer;
  656. if ( !fIsEmbeddedStruct )
  657. {
  658. // Align the buffer for marshalling conformance info.
  659. ALIGN(pStubMsg->Buffer,3);
  660. // Mark the location in the buffer where the conformance will be marshalled.
  661. pStubMsg->BufferMark = pStubMsg->Buffer;
  662. // Increment buffer pointer past where conformance will be marshalled.
  663. pStubMsg->Buffer += 4;
  664. }
  665. // else BufferMark is set by the ComplexStruct code.
  666. // Save the structure's alignment.
  667. Alignment = pFormat[1];
  668. // Increment format string to struct size field.
  669. pFormat += 2;
  670. // Get non-conformance struct size and increment format string.
  671. StructSize = (uint) *((ushort *&)pFormat)++;
  672. // Get conformant array's description.
  673. pFormatArray = pFormat + *((signed short *)pFormat);
  674. // Align buffer for struct
  675. ZeroOutGapAndAlign(pStubMsg, Alignment);
  676. pBuffer = pStubMsg->Buffer;
  677. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  678. pMemory,
  679. StructSize );
  680. // Set stub message buffer pointer past non-conformant part of struct.
  681. pStubMsg->Buffer += StructSize;
  682. //
  683. // Call the correct private array or string marshalling routine.
  684. // We must pass a memory pointer to the beginning of the array/string.
  685. //
  686. if ( *pFormatArray == FC_CVARRAY )
  687. {
  688. NdrpConformantVaryingArrayMarshall( pStubMsg,
  689. pMemory + StructSize,
  690. pFormatArray );
  691. }
  692. else
  693. {
  694. NdrpConformantStringMarshall( pStubMsg,
  695. pMemory + StructSize,
  696. pFormatArray );
  697. }
  698. // Increment format string past the offset_to_array_description<2> field.
  699. pFormat += 2;
  700. //
  701. // Marshall embedded pointers.
  702. //
  703. if ( *pFormat == FC_PP )
  704. {
  705. // Mark the start of the structure in the buffer.
  706. pStubMsg->BufferMark = pBuffer;
  707. pStubMsg->MaxCount = pStubMsg->ActualCount;
  708. NdrpEmbeddedPointerMarshall( pStubMsg,
  709. pMemory,
  710. pFormat );
  711. }
  712. // Only a complex struct may set up this flag for embedding.
  713. // Set the reverse flag to signal that array has been marshaled.
  714. if ( fIsEmbeddedStruct )
  715. SET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  716. return 0;
  717. }
  718. #if 0
  719. unsigned char * RPC_ENTRY
  720. NdrHardStructMarshall(
  721. PMIDL_STUB_MESSAGE pStubMsg,
  722. uchar * pMemory,
  723. PFORMAT_STRING pFormat )
  724. /*++
  725. Routine description :
  726. Marshalls a hard structure.
  727. Used for FC_HARD_STRUCT.
  728. Arguments :
  729. pStubMsg - Pointer to the stub message.
  730. pMemory - Pointer to the structure being marshalled.
  731. pFormat - Structure's format string description.
  732. Return :
  733. None.
  734. --*/
  735. {
  736. ALIGN(pStubMsg->Buffer,pFormat[1]);
  737. pFormat += 8;
  738. //
  739. // Do any needed enum16 exception check.
  740. //
  741. if ( *((short *)pFormat) != (short) -1 )
  742. {
  743. if ( *((int *)(pMemory + *((ushort *)pFormat))) & ~((int)0x7fff) )
  744. {
  745. RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  746. }
  747. }
  748. pFormat += 2;
  749. RpcpMemoryCopy( pStubMsg->Buffer,
  750. pMemory,
  751. *((ushort *)pFormat) );
  752. pStubMsg->Buffer += *((ushort *)pFormat)++;
  753. //
  754. // See if we have a union.
  755. //
  756. if ( *((short *)&pFormat[2]) )
  757. {
  758. pMemory += *((ushort *)pFormat)++;
  759. pFormat += *((short *)pFormat);
  760. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  761. pMemory,
  762. pFormat );
  763. }
  764. return 0;
  765. }
  766. #endif // 0
  767. unsigned char * RPC_ENTRY
  768. NdrComplexStructMarshall(
  769. PMIDL_STUB_MESSAGE pStubMsg,
  770. uchar * pMemory,
  771. PFORMAT_STRING pFormat )
  772. /*++
  773. Routine description :
  774. Marshalls a complex structure.
  775. Used for FC_BOGUS_STRUCT.
  776. Arguments :
  777. pStubMsg - Pointer to the stub message.
  778. pMemory - Pointer to the structure being marshalled.
  779. pFormat - Structure's format string description.
  780. Return :
  781. None.
  782. Notes :
  783. pStubMsg->BufferMark is set to a place where conformance would be marhaled.
  784. pStubMsg->pPointerBufferMark is a pointee buffer mark a usual.
  785. --*/
  786. {
  787. uchar * pBufferSave;
  788. uchar * pBufferMark;
  789. uchar * pMemorySave;
  790. PFORMAT_STRING pFormatPointers;
  791. PFORMAT_STRING pFormatArray;
  792. PFORMAT_STRING pFormatSave;
  793. PFORMAT_STRING pFormatComplex;
  794. long Alignment;
  795. long Align8Mod;
  796. uchar fSetPointerBufferMark;
  797. uchar fIsEmbeddedStruct = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  798. BOOL fEmbedConfStructContext;
  799. // Get struct's wire alignment.
  800. Alignment = pFormat[1];
  801. //
  802. // This is used for support of structs with doubles passed on an
  803. // i386 stack.
  804. //
  805. // A cast to long is what we need.
  806. Align8Mod = 0x7 & PtrToLong( pMemory );
  807. pFormatSave = pFormat;
  808. pBufferSave = pStubMsg->Buffer;
  809. pMemorySave = pStubMsg->Memory;
  810. pStubMsg->Memory = pMemory;
  811. // Increment to conformant array offset field.
  812. pFormat += 4;
  813. // Get conformant array description.
  814. if ( *((ushort *)pFormat) )
  815. {
  816. pFormatArray = pFormat + *((signed short *)pFormat);
  817. if ( !fIsEmbeddedStruct )
  818. {
  819. // Align for conformance marshalling.
  820. ALIGN(pStubMsg->Buffer,3);
  821. // Remember where the conformance count(s) will be marshalled.
  822. pStubMsg->BufferMark = pStubMsg->Buffer;
  823. // Increment the buffer pointer 4 bytes for every array dimension.
  824. pStubMsg->Buffer += NdrpArrayDimensions( pStubMsg, pFormatArray, FALSE ) * 4;
  825. }
  826. }
  827. else
  828. pFormatArray = 0;
  829. // Mark the place to marshal conformant size(s), this may come from upper levels.
  830. pBufferMark = pStubMsg->BufferMark;
  831. pFormat += 2;
  832. // Get pointer layout description.
  833. if ( *((ushort *)pFormat) )
  834. pFormatPointers = pFormat + *((ushort *)pFormat);
  835. else
  836. pFormatPointers = 0;
  837. pFormat += 2;
  838. // Align buffer on struct's alignment.
  839. ZeroOutGapAndAlign(pStubMsg,Alignment);
  840. //
  841. // If the the stub message PointerBufferMark field is 0, then determine
  842. // the position in the buffer where pointees will be marshalled.
  843. //
  844. // We have to do this to handle embedded pointers.
  845. //
  846. if ( fSetPointerBufferMark = ! pStubMsg->PointerBufferMark )
  847. {
  848. BOOL fOldIgnore;
  849. ulong BufferLenOffset;
  850. fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
  851. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  852. //
  853. // Set BufferLength equal to the current buffer pointer, and then
  854. // when we return from NdrComplexStructBufferSize it will pointer to
  855. // the location in the buffer where the pointees should be marshalled.
  856. // pStubMsg->BufferLength = pBufferSave;
  857. // Instead of pointer, we now calculate pointer increment explicitly.
  858. // Set the pointer alignment as a base.
  859. // We use pBufferSave as the sizing routine accounts for the conf sizes.
  860. //
  861. BufferLenOffset = 0xf & PtrToUlong( pBufferSave );
  862. ulong BufferLengthSave = pStubMsg->BufferLength;
  863. pStubMsg->BufferLength = BufferLenOffset;
  864. NdrComplexStructBufferSize( pStubMsg,
  865. pMemory,
  866. pFormatSave );
  867. // Pointer increment including alignments.
  868. BufferLenOffset = pStubMsg->BufferLength - BufferLenOffset;
  869. // Set the location in the buffer where pointees will be marshalled.
  870. pStubMsg->PointerBufferMark = pBufferSave + BufferLenOffset;
  871. pStubMsg->BufferLength = BufferLengthSave;
  872. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  873. // in NDR20, we have trailing pad issue where if a complex struct contains pointer to simple type
  874. // and trailing simple type, the first pointee will be written immediately after the last element of
  875. // the structure, BEFORE we write the last flat element. If we zero out the alignment gap
  876. // we only need to zero out when there is pointer in the struct.
  877. if ( pFormatPointers )
  878. {
  879. ULONG_PTR CopyLength = (ulong)( ( (ULONG_PTR)(pBufferSave + BufferLenOffset + 3 ) & ~3) - (ULONG_PTR)pBufferSave);
  880. // we need to memset always.
  881. memset( pBufferSave, 0, CopyLength );
  882. }
  883. }
  884. fEmbedConfStructContext = fIsEmbeddedStruct ||
  885. pFormatArray && FixWireRepForDComVerGTE54( pStubMsg );
  886. RESET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  887. //
  888. // Marshall the structure member by member.
  889. //
  890. for ( ; ; pFormat++ )
  891. {
  892. switch ( *pFormat )
  893. {
  894. //
  895. // Simple types.
  896. //
  897. case FC_CHAR :
  898. case FC_BYTE :
  899. case FC_SMALL :
  900. case FC_USMALL:
  901. *(pStubMsg->Buffer)++ = *pMemory;
  902. pMemory += 1;
  903. break;
  904. case FC_ENUM16 :
  905. if ( *((int *)pMemory) & ~((int)0x7fff) )
  906. {
  907. RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  908. }
  909. ALIGN(pStubMsg->Buffer,1);
  910. *((ushort *&)pStubMsg->Buffer)++ = *((ushort *)pMemory);
  911. pMemory += 4;
  912. break;
  913. case FC_WCHAR :
  914. case FC_SHORT :
  915. case FC_USHORT:
  916. ALIGN(pStubMsg->Buffer,1);
  917. *((ushort *&)pStubMsg->Buffer)++ = *((ushort *)pMemory);
  918. pMemory += 2;
  919. break;
  920. #if defined(__RPC_WIN64__)
  921. case FC_INT3264 :
  922. case FC_UINT3264 :
  923. ALIGN( pStubMsg->Buffer, 3 );
  924. * ((ulong *&)pStubMsg->Buffer)++ = *((ulong *)pMemory);
  925. pMemory += 8;
  926. break;
  927. #endif
  928. case FC_LONG :
  929. case FC_ULONG:
  930. case FC_FLOAT :
  931. case FC_ENUM32 :
  932. ALIGN( pStubMsg->Buffer, 3 );
  933. * ((ulong *&)pStubMsg->Buffer)++ = *((ulong *)pMemory);
  934. pMemory += 4;
  935. break;
  936. case FC_HYPER :
  937. case FC_DOUBLE :
  938. ALIGN( pStubMsg->Buffer, 7 );
  939. *((ulong *&)pStubMsg->Buffer)++ = *((ulong *)pMemory);
  940. *((ulong *&)pStubMsg->Buffer)++ = *((ulong *)(pMemory + 4));
  941. pMemory += 8;
  942. break;
  943. case FC_IGNORE :
  944. ALIGN(pStubMsg->Buffer,3);
  945. pStubMsg->Buffer += PTR_WIRE_SIZE;
  946. pMemory += PTR_MEM_SIZE;
  947. break;
  948. case FC_POINTER :
  949. {
  950. ALIGN( pStubMsg->Buffer, 0x3 );
  951. uchar *pPointerId = pStubMsg->Buffer;
  952. pStubMsg->Buffer += PTR_WIRE_SIZE;
  953. NDR_ASSERT(pFormatPointers, "NdrComplexStructMarshall: pointer field but no pointer layout");
  954. {
  955. POINTER_BUFFER_SWAP_CONTEXT NewContext(pStubMsg);
  956. NdrpPointerMarshall( pStubMsg,
  957. pPointerId,
  958. *((uchar **)pMemory),
  959. pFormatPointers );
  960. }
  961. //
  962. // Increment memory pointers past the pointer.
  963. //
  964. pMemory += PTR_MEM_SIZE;
  965. pFormatPointers += 4;
  966. break;
  967. }
  968. //
  969. // Embedded complex types.
  970. //
  971. case FC_EMBEDDED_COMPLEX :
  972. // Increment memory pointer by padding.
  973. pMemory += pFormat[1];
  974. pFormat += 2;
  975. // Get the type's description.
  976. pFormatComplex = pFormat + *((signed short UNALIGNED *)pFormat);
  977. if ( FC_IP == *pFormatComplex )
  978. {
  979. // Treat the same as an embedded pointer
  980. ALIGN( pStubMsg->Buffer, 0x3 );
  981. uchar *pPointerId = pStubMsg->Buffer;
  982. pStubMsg->Buffer += PTR_WIRE_SIZE;
  983. {
  984. POINTER_BUFFER_SWAP_CONTEXT NewContext(pStubMsg);
  985. NdrpPointerMarshall( pStubMsg,
  986. pPointerId,
  987. *((uchar **)pMemory),
  988. pFormatComplex );
  989. }
  990. pMemory += PTR_MEM_SIZE;
  991. pFormat++;
  992. break;
  993. }
  994. // Context needed for the embedded conf struct.
  995. //
  996. pStubMsg->BufferMark = pBufferMark;
  997. if ( fEmbedConfStructContext )
  998. SET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  999. // Marshall complex type.
  1000. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormatComplex)])
  1001. ( pStubMsg,
  1002. pMemory,
  1003. pFormatComplex );
  1004. //
  1005. // Increment the memory pointer.
  1006. //
  1007. pMemory = NdrpMemoryIncrement( pStubMsg,
  1008. pMemory,
  1009. pFormatComplex );
  1010. RESET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  1011. //
  1012. // Increment the main format string one byte. The loop
  1013. // will increment it one more byte past the offset field.
  1014. //
  1015. pFormat++;
  1016. break;
  1017. case FC_ALIGNM2 :
  1018. ALIGN( pMemory, 0x1 );
  1019. break;
  1020. case FC_ALIGNM4 :
  1021. ALIGN( pMemory, 0x3 );
  1022. break;
  1023. case FC_ALIGNM8 :
  1024. //
  1025. // We have to play some tricks for the i386 to handle the case
  1026. // when an 8 byte aligned structure is passed by value. The
  1027. // alignment of the struct on the stack is not guaranteed to be
  1028. // on an 8 byte boundary.
  1029. //
  1030. pMemory -= Align8Mod;
  1031. ALIGN(pMemory, 0x7 );
  1032. pMemory += Align8Mod;
  1033. break;
  1034. case FC_STRUCTPAD1 :
  1035. case FC_STRUCTPAD2 :
  1036. case FC_STRUCTPAD3 :
  1037. case FC_STRUCTPAD4 :
  1038. case FC_STRUCTPAD5 :
  1039. case FC_STRUCTPAD6 :
  1040. case FC_STRUCTPAD7 :
  1041. //
  1042. // Increment memory pointer by amount of padding.
  1043. //
  1044. pMemory += (*pFormat - FC_STRUCTPAD1) + 1;
  1045. break;
  1046. case FC_STRUCTPADN :
  1047. // FC_STRUCTPADN 0 <unsigned short>
  1048. pMemory += *(((unsigned short *)pFormat) + 1);
  1049. pFormat += 3;
  1050. break;
  1051. case FC_PAD :
  1052. break;
  1053. //
  1054. // Done with layout.
  1055. //
  1056. case FC_END :
  1057. goto ComplexMarshallEnd;
  1058. default :
  1059. NDR_ASSERT(0,"NdrComplexStructMarshall : bad format char");
  1060. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1061. return 0;
  1062. } // switch
  1063. } // for
  1064. ComplexMarshallEnd:
  1065. //
  1066. // Marshall conformant array if we have one.
  1067. // .. but not when embedded and not when it had been marshaled by conf struct.
  1068. //
  1069. if ( pFormatArray && !fIsEmbeddedStruct &&
  1070. ! IS_CONF_ARRAY_DONE( pStubMsg->uFlags ) )
  1071. {
  1072. // Normal case: top level marshaling.
  1073. PPRIVATE_MARSHALL_ROUTINE pfnPMarshall;
  1074. switch ( *pFormatArray )
  1075. {
  1076. case FC_CARRAY :
  1077. pfnPMarshall = NdrpConformantArrayMarshall;
  1078. break;
  1079. case FC_CVARRAY :
  1080. pfnPMarshall = NdrpConformantVaryingArrayMarshall;
  1081. break;
  1082. case FC_BOGUS_ARRAY :
  1083. pfnPMarshall = NdrpComplexArrayMarshall;
  1084. break;
  1085. case FC_C_WSTRING :
  1086. ALIGN(pMemory,1);
  1087. // fall through
  1088. // case FC_C_CSTRING :
  1089. // case FC_C_BSTRING :
  1090. // case FC_C_SSTRING :
  1091. default :
  1092. pfnPMarshall = NdrpConformantStringMarshall;
  1093. break;
  1094. }
  1095. //
  1096. // Mark where the conformance count(s) will be marshalled.
  1097. //
  1098. pStubMsg->BufferMark = pBufferMark;
  1099. // Marshall the array.
  1100. (*pfnPMarshall)( pStubMsg,
  1101. pMemory,
  1102. pFormatArray );
  1103. }
  1104. //
  1105. // Now fix up the stub message Buffer field if we set the PointerBufferMark
  1106. // field.
  1107. //
  1108. if ( fSetPointerBufferMark )
  1109. {
  1110. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  1111. pStubMsg->PointerBufferMark = 0;
  1112. }
  1113. pStubMsg->Memory = pMemorySave;
  1114. if ( fIsEmbeddedStruct )
  1115. SET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  1116. else
  1117. RESET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  1118. return 0;
  1119. }
  1120. unsigned char * RPC_ENTRY
  1121. NdrNonConformantStringMarshall(
  1122. PMIDL_STUB_MESSAGE pStubMsg,
  1123. uchar * pMemory,
  1124. PFORMAT_STRING pFormat )
  1125. /*++
  1126. Routine description :
  1127. Marshalls a non conformant string.
  1128. Used for FC_CSTRING, FC_WSTRING, FC_SSTRING, and FC_BSTRING (NT Beta2
  1129. compatability only).
  1130. Arguments :
  1131. pStubMsg - Pointer to the stub message.
  1132. pMemory - Pointer to the string to be marshalled.
  1133. pFormat - String's format string description.
  1134. Return :
  1135. None.
  1136. --*/
  1137. {
  1138. uint Count;
  1139. uint CopySize;
  1140. // Align the buffer for offset and count marshalling.
  1141. ALIGN(pStubMsg->Buffer,3);
  1142. switch ( *pFormat )
  1143. {
  1144. case FC_CSTRING :
  1145. case FC_BSTRING :
  1146. CopySize = Count = MIDL_ascii_strlen((char *)pMemory) + 1;
  1147. break;
  1148. case FC_WSTRING :
  1149. Count = wcslen((wchar_t *)pMemory) + 1;
  1150. CopySize = Count * sizeof(wchar_t);
  1151. break;
  1152. case FC_SSTRING :
  1153. Count = NdrpStringStructLen( pMemory, pFormat[1] ) + 1;
  1154. CopySize = Count * pFormat[1];
  1155. break;
  1156. default :
  1157. NDR_ASSERT(0,"NdrNonConformantStringMarshall : bad format char");
  1158. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1159. return 0;
  1160. }
  1161. // Marshall variance.
  1162. *((ulong *&)pStubMsg->Buffer)++ = 0;
  1163. *((ulong *&)pStubMsg->Buffer)++ = Count;
  1164. // Copy the string.
  1165. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1166. pMemory,
  1167. CopySize );
  1168. // Update buffer pointer.
  1169. pStubMsg->Buffer += CopySize;
  1170. return 0;
  1171. }
  1172. unsigned char * RPC_ENTRY
  1173. NdrConformantStringMarshall(
  1174. PMIDL_STUB_MESSAGE pStubMsg,
  1175. uchar * pMemory,
  1176. PFORMAT_STRING pFormat )
  1177. /*++
  1178. Routine description :
  1179. Marshalls a top level conformant string.
  1180. Used for FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and FC_C_BSTRING
  1181. (NT Beta2 compatability only).
  1182. Arguments :
  1183. pStubMsg - Pointer to the stub message.
  1184. pMemory - Pointer to the string to be marshalled.
  1185. pFormat - String's format string description.
  1186. Return :
  1187. None.
  1188. --*/
  1189. {
  1190. if ( pStubMsg->pArrayInfo != 0 )
  1191. {
  1192. //
  1193. // If this is part of a multidimensional array then we get the location
  1194. // where the conformance is marshalled from a special place.
  1195. //
  1196. pStubMsg->BufferMark = ( uchar * )
  1197. &(pStubMsg->pArrayInfo->
  1198. BufferConformanceMark[pStubMsg->pArrayInfo->Dimension]);
  1199. }
  1200. else
  1201. {
  1202. // Align the buffer for max count marshalling.
  1203. ALIGN(pStubMsg->Buffer,3);
  1204. // Mark where the max count will be marshalled.
  1205. pStubMsg->BufferMark = pStubMsg->Buffer;
  1206. // Increment the buffer past where the max count will be marshalled.
  1207. pStubMsg->Buffer += 4;
  1208. }
  1209. // Call the private marshalling routine.
  1210. NdrpConformantStringMarshall( pStubMsg,
  1211. pMemory,
  1212. pFormat );
  1213. return 0;
  1214. }
  1215. void
  1216. NdrpConformantStringMarshall(
  1217. PMIDL_STUB_MESSAGE pStubMsg,
  1218. uchar * pMemory,
  1219. PFORMAT_STRING pFormat )
  1220. /*++
  1221. Routine description :
  1222. Private routine for marshalling a conformant string. This is the
  1223. entry point for marshalling an embedded conformant strings.
  1224. Used for FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and FC_C_BSTRING
  1225. (NT Beta2 compatability only).
  1226. Arguments :
  1227. pStubMsg - Pointer to the stub message.
  1228. pMemory - Pointer to the string to be marshalled.
  1229. pFormat - String's format string description.
  1230. Return :
  1231. None.
  1232. --*/
  1233. {
  1234. ulong MaxCount;
  1235. uint ActualCount, CopySize;
  1236. BOOL IsSized;
  1237. IsSized = (pFormat[1] == FC_STRING_SIZED);
  1238. // Compute the element count of the string and the total copy size.
  1239. switch ( *pFormat )
  1240. {
  1241. case FC_C_CSTRING :
  1242. case FC_C_BSTRING :
  1243. CopySize = ActualCount = MIDL_ascii_strlen((char *)pMemory) + 1;
  1244. break;
  1245. case FC_C_WSTRING :
  1246. ActualCount = wcslen((wchar_t *)pMemory) + 1;
  1247. CopySize = ActualCount * sizeof(wchar_t);
  1248. break;
  1249. case FC_C_SSTRING :
  1250. ActualCount = NdrpStringStructLen( pMemory, pFormat[1] ) + 1;
  1251. CopySize = ActualCount * pFormat[1];
  1252. // Redo this check correctly.
  1253. IsSized = (pFormat[2] == FC_STRING_SIZED);
  1254. break;
  1255. default :
  1256. NDR_ASSERT(0,"NdrpConformantStringMarshall : bad format char");
  1257. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1258. return;
  1259. }
  1260. //
  1261. // If the string is sized then compute the max count, otherwise the
  1262. // max count is equal to the actual count.
  1263. //
  1264. if ( IsSized )
  1265. {
  1266. MaxCount = (ulong) NdrpComputeConformance( pStubMsg,
  1267. pMemory,
  1268. pFormat );
  1269. }
  1270. else
  1271. {
  1272. MaxCount = ActualCount;
  1273. }
  1274. // Marshall the max count.
  1275. *((ulong *)pStubMsg->BufferMark) = MaxCount;
  1276. // Align the buffer for variance marshalling.
  1277. ALIGN(pStubMsg->Buffer,3);
  1278. // Marshall variance.
  1279. *((ulong *&)pStubMsg->Buffer)++ = 0;
  1280. *((ulong *&)pStubMsg->Buffer)++ = ActualCount;
  1281. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1282. pMemory,
  1283. CopySize );
  1284. // Update the Buffer pointer.
  1285. pStubMsg->Buffer += CopySize;
  1286. }
  1287. unsigned char * RPC_ENTRY
  1288. NdrFixedArrayMarshall(
  1289. PMIDL_STUB_MESSAGE pStubMsg,
  1290. uchar * pMemory,
  1291. PFORMAT_STRING pFormat )
  1292. /*++
  1293. Routine Description :
  1294. Marshalls a fixed array of any number of dimensions.
  1295. Used for FC_SMFARRAY and FC_LGFARRAY.
  1296. Arguments :
  1297. pStubMsg - Pointer to the stub message.
  1298. pMemory - Pointer to the array to be marshalled.
  1299. pFormat - Array's format string description.
  1300. Return :
  1301. None.
  1302. --*/
  1303. {
  1304. uint Size;
  1305. // Align the buffer.
  1306. ZeroOutGapAndAlign(pStubMsg,pFormat[1]);
  1307. // Get total array size.
  1308. if ( *pFormat == FC_SMFARRAY )
  1309. {
  1310. pFormat += 2;
  1311. Size = (ulong) *((ushort *&)pFormat)++;
  1312. }
  1313. else // *pFormat == FC_LGFARRAY
  1314. {
  1315. pFormat += 2;
  1316. Size = *((ulong UNALIGNED *&)pFormat)++;
  1317. }
  1318. // Copy the array.
  1319. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1320. pMemory,
  1321. Size );
  1322. // Increment stub message buffer pointer.
  1323. pStubMsg->Buffer += Size;
  1324. // Marshall embedded pointers.
  1325. if ( *pFormat == FC_PP )
  1326. {
  1327. // Mark the start of the array in the buffer.
  1328. pStubMsg->BufferMark = pStubMsg->Buffer - Size;
  1329. NdrpEmbeddedPointerMarshall( pStubMsg,
  1330. pMemory,
  1331. pFormat );
  1332. }
  1333. return 0;
  1334. }
  1335. unsigned char * RPC_ENTRY
  1336. NdrConformantArrayMarshall(
  1337. PMIDL_STUB_MESSAGE pStubMsg,
  1338. uchar * pMemory,
  1339. PFORMAT_STRING pFormat )
  1340. /*++
  1341. Routine Description :
  1342. Marshalls a top level one dimensional conformant array.
  1343. Used for FC_CARRAY.
  1344. Arguments :
  1345. pStubMsg - Pointer to the stub message.
  1346. pMemory - Pointer to the array being marshalled.
  1347. pFormat - Array's format string description.
  1348. Return :
  1349. None.
  1350. --*/
  1351. {
  1352. // Align the buffer for conformance marshalling.
  1353. ALIGN(pStubMsg->Buffer,3);
  1354. // Mark where the conformance will be marshalled.
  1355. pStubMsg->BufferMark = pStubMsg->Buffer;
  1356. // Increment past where the conformance will go.
  1357. pStubMsg->Buffer += 4;
  1358. // Call the private marshalling routine to do the work.
  1359. NdrpConformantArrayMarshall( pStubMsg,
  1360. pMemory,
  1361. pFormat );
  1362. return 0;
  1363. }
  1364. void
  1365. NdrpConformantArrayMarshall(
  1366. PMIDL_STUB_MESSAGE pStubMsg,
  1367. uchar * pMemory,
  1368. PFORMAT_STRING pFormat )
  1369. /*++
  1370. Routine Description :
  1371. Private routine for marshalling a one dimensional conformant array.
  1372. This is the entry point for marshalling an embedded conformant array.
  1373. Used for FC_CARRAY.
  1374. Arguments :
  1375. pStubMsg - Pointer to the stub message.
  1376. pMemory - Pointer to the array being marshalled.
  1377. pFormat - Array's format string description.
  1378. Return :
  1379. None.
  1380. --*/
  1381. {
  1382. ulong Count;
  1383. uint CopySize;
  1384. // Compute conformance information.
  1385. Count = (ulong) NdrpComputeConformance( pStubMsg,
  1386. pMemory,
  1387. pFormat );
  1388. // Marshall the conformance.
  1389. *((ulong *)pStubMsg->BufferMark) = Count;
  1390. //
  1391. // Return if size is 0.
  1392. //
  1393. if ( ! Count )
  1394. return;
  1395. ZeroOutGapAndAlign(pStubMsg,pFormat[1]);
  1396. // Compute the total array size in bytes.
  1397. CopySize = Count * *((ushort *)(pFormat + 2));
  1398. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1399. pMemory,
  1400. CopySize );
  1401. // Update buffer pointer.
  1402. pStubMsg->Buffer += CopySize;
  1403. // Increment to possible pointer layout.
  1404. pFormat += 8;
  1405. CORRELATION_DESC_INCREMENT( pFormat );
  1406. // Marshall embedded pointers.
  1407. if ( *pFormat == FC_PP )
  1408. {
  1409. //
  1410. // Mark the start of the array in the buffer.
  1411. //
  1412. pStubMsg->BufferMark = pStubMsg->Buffer - CopySize;
  1413. NdrpEmbeddedPointerMarshall( pStubMsg,
  1414. pMemory,
  1415. pFormat );
  1416. }
  1417. }
  1418. unsigned char * RPC_ENTRY
  1419. NdrConformantVaryingArrayMarshall(
  1420. PMIDL_STUB_MESSAGE pStubMsg,
  1421. uchar * pMemory,
  1422. PFORMAT_STRING pFormat )
  1423. /*++
  1424. Routine Description :
  1425. Marshalls a top level one dimensional conformant varying array.
  1426. Used for FC_CVARRAY.
  1427. Arguments :
  1428. pStubMsg - Pointer to the stub message.
  1429. pMemory - Pointer to the array being marshalled.
  1430. pFormat - Array's format string description.
  1431. Return :
  1432. None.
  1433. --*/
  1434. {
  1435. // Align the buffer for conformance marshalling.
  1436. ALIGN(pStubMsg->Buffer,3);
  1437. // Mark where the conformance will be marshalled.
  1438. pStubMsg->BufferMark = pStubMsg->Buffer;
  1439. // Increment past where the conformance will go.
  1440. pStubMsg->Buffer += 4;
  1441. // Call the private marshalling routine to do the work.
  1442. NdrpConformantVaryingArrayMarshall( pStubMsg,
  1443. pMemory,
  1444. pFormat );
  1445. return 0;
  1446. }
  1447. void
  1448. NdrpConformantVaryingArrayMarshall(
  1449. PMIDL_STUB_MESSAGE pStubMsg,
  1450. uchar * pMemory,
  1451. PFORMAT_STRING pFormat )
  1452. /*++
  1453. Routine Description :
  1454. Private routine for marshalling a one dimensional conformant varying array.
  1455. This is the entry point for marshalling an embedded conformant varying
  1456. array.
  1457. Used for FC_CVARRAY.
  1458. Arguments :
  1459. pStubMsg - Pointer to the stub message.
  1460. pMemory - Pointer to the array to be marshalled.
  1461. pFormat - Array's format string description.
  1462. Return :
  1463. None.
  1464. --*/
  1465. {
  1466. uint CopyOffset, CopySize;
  1467. ushort ElemSize;
  1468. // Compute and marshall the conformant size.
  1469. *((ulong *)pStubMsg->BufferMark) = (ulong) NdrpComputeConformance( pStubMsg,
  1470. pMemory,
  1471. pFormat );
  1472. // Compute variance offset and count.
  1473. NdrpComputeVariance( pStubMsg,
  1474. pMemory,
  1475. pFormat );
  1476. // Align the buffer for variance marshalling.
  1477. ALIGN(pStubMsg->Buffer,3);
  1478. // Marshall variance.
  1479. *((ulong *&)pStubMsg->Buffer)++ = pStubMsg->Offset;
  1480. *((ulong *&)pStubMsg->Buffer)++ = pStubMsg->ActualCount;
  1481. //
  1482. // Return if length is 0.
  1483. //
  1484. if ( ! pStubMsg->ActualCount )
  1485. return;
  1486. ZeroOutGapAndAlign(pStubMsg, pFormat[1]);
  1487. ElemSize = *((ushort *)(pFormat + 2));
  1488. // Compute byte offset and size for the array copy.
  1489. CopyOffset = pStubMsg->Offset * ElemSize;
  1490. CopySize = pStubMsg->ActualCount * ElemSize;
  1491. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1492. pMemory + CopyOffset,
  1493. CopySize );
  1494. pStubMsg->Buffer += CopySize;
  1495. // Increment to a possible pointer layout.
  1496. pFormat += 12;
  1497. CORRELATION_DESC_INCREMENT( pFormat );
  1498. CORRELATION_DESC_INCREMENT( pFormat );
  1499. // Marshall embedded pointers.
  1500. if ( *pFormat == FC_PP )
  1501. {
  1502. //
  1503. // Set the MaxCount field equal to the ActualCount field. The pointer
  1504. // marshalling routine uses the MaxCount field to determine the number
  1505. // of times an FC_VARIABLE_REPEAT pointer is marshalled. In the face
  1506. // of variance the correct number of time is the ActualCount, not the
  1507. // the MaxCount.
  1508. //
  1509. pStubMsg->MaxCount = pStubMsg->ActualCount;
  1510. //
  1511. // Mark the start of the array in the buffer.
  1512. //
  1513. pStubMsg->BufferMark = pStubMsg->Buffer - CopySize;
  1514. NdrpEmbeddedPointerMarshall( pStubMsg,
  1515. pMemory,
  1516. pFormat );
  1517. }
  1518. }
  1519. unsigned char * RPC_ENTRY
  1520. NdrVaryingArrayMarshall(
  1521. PMIDL_STUB_MESSAGE pStubMsg,
  1522. uchar * pMemory,
  1523. PFORMAT_STRING pFormat )
  1524. /*++
  1525. Routine Description :
  1526. Marshalls a top level or embedded one dimensional varying array.
  1527. Used for FC_SMVARRAY and FC_LGVARRAY.
  1528. Arguments :
  1529. pStubMsg - Pointer to the stub message.
  1530. pMemory - Pointer to the array being marshalled.
  1531. pFormat - Array's format string description.
  1532. Return :
  1533. None.
  1534. --*/
  1535. {
  1536. uint CopyOffset, CopySize;
  1537. ushort ElemSize;
  1538. // Compute the variance offset and count.
  1539. NdrpComputeVariance( pStubMsg,
  1540. pMemory,
  1541. pFormat );
  1542. // Align the buffer for variance marshalling.
  1543. ALIGN(pStubMsg->Buffer,3);
  1544. // Marshall variance.
  1545. *((ulong *&)pStubMsg->Buffer)++ = pStubMsg->Offset;
  1546. *((ulong *&)pStubMsg->Buffer)++ = pStubMsg->ActualCount;
  1547. //
  1548. // Return if length is 0.
  1549. //
  1550. if ( ! pStubMsg->ActualCount )
  1551. return 0;
  1552. ZeroOutGapAndAlign(pStubMsg, pFormat[1]);
  1553. // Increment the format string to the element_size field.
  1554. if ( *pFormat == FC_SMVARRAY )
  1555. pFormat += 6;
  1556. else // *pFormat == FC_LGVARRAY
  1557. pFormat += 10;
  1558. // Get element size.
  1559. ElemSize = *((ushort *)pFormat);
  1560. //
  1561. // Compute the byte offset from the beginning of the array for the copy
  1562. // and the number of bytes to copy.
  1563. //
  1564. CopyOffset = pStubMsg->Offset * ElemSize;
  1565. CopySize = pStubMsg->ActualCount * ElemSize;
  1566. // Copy the array.
  1567. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1568. pMemory + CopyOffset,
  1569. CopySize );
  1570. // Update buffer pointer.
  1571. pStubMsg->Buffer += CopySize;
  1572. // Increment format string to possible pointer layout.
  1573. pFormat += 6;
  1574. CORRELATION_DESC_INCREMENT( pFormat );
  1575. // Marshall embedded pointers.
  1576. if ( *pFormat == FC_PP )
  1577. {
  1578. // Mark the start of the array in the buffer.
  1579. pStubMsg->BufferMark = pStubMsg->Buffer - CopySize;
  1580. //
  1581. // Set the MaxCount field equal to the ActualCount field. The pointer
  1582. // marshalling routine uses the MaxCount field to determine the number
  1583. // of times an FC_VARIABLE_REPEAT pointer is marshalled. In the face
  1584. // of variance the correct number of time is the ActualCount, not the
  1585. // the MaxCount.
  1586. //
  1587. pStubMsg->MaxCount = pStubMsg->ActualCount;
  1588. //
  1589. // Marshall the embedded pointers.
  1590. // Make sure to pass a memory pointer to the first array element
  1591. // which is actually being marshalled.
  1592. //
  1593. NdrpEmbeddedPointerMarshall( pStubMsg,
  1594. pMemory + CopyOffset,
  1595. pFormat );
  1596. }
  1597. return 0;
  1598. }
  1599. unsigned char * RPC_ENTRY
  1600. NdrComplexArrayMarshall(
  1601. PMIDL_STUB_MESSAGE pStubMsg,
  1602. uchar * pMemory,
  1603. PFORMAT_STRING pFormat )
  1604. /*++
  1605. Routine Description :
  1606. Marshalls a top level complex array.
  1607. Used for FC_BOGUS_STRUCT.
  1608. Arguments :
  1609. pStubMsg - Pointer to the stub message.
  1610. pMemory - Pointer to the array being marshalled.
  1611. pFormat - Array's format string description.
  1612. Return :
  1613. None.
  1614. --*/
  1615. {
  1616. BOOL fSetPointerBufferMark;
  1617. PFORMAT_STRING pFormatPP;
  1618. //
  1619. // Setting this flag means that the array is not embedded inside of
  1620. // another complex struct or array.
  1621. //
  1622. pFormatPP = pFormat + 12;
  1623. CORRELATION_DESC_INCREMENT( pFormatPP );
  1624. CORRELATION_DESC_INCREMENT( pFormatPP );
  1625. fSetPointerBufferMark = (! pStubMsg->PointerBufferMark) &&
  1626. (*pFormatPP != FC_RP);
  1627. if ( fSetPointerBufferMark )
  1628. {
  1629. BOOL fOldIgnore;
  1630. ULONG_PTR MaxCountSave;
  1631. ulong Offset, ActualCount;
  1632. ulong BufferLenOffset;
  1633. //
  1634. // Save the current conformance and variance fields. The sizing
  1635. // routine can overwrite them.
  1636. //
  1637. MaxCountSave = pStubMsg->MaxCount;
  1638. Offset = pStubMsg->Offset;
  1639. ActualCount = pStubMsg->ActualCount;
  1640. fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
  1641. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  1642. //
  1643. // Set BufferLength equal to the current buffer pointer, and then
  1644. // when we return from NdrComplexArrayBufferSize it will point to
  1645. // the location in the buffer where the pointers should be marshalled
  1646. // into.
  1647. // Instead of pointer, we now calculate pointer increment explicitly.
  1648. //
  1649. // Set the pointer alignment as a base.
  1650. BufferLenOffset = 0xf & PtrToUlong( pStubMsg->Buffer );
  1651. ulong BufferLengthSave = pStubMsg->BufferLength;
  1652. pStubMsg->BufferLength = BufferLenOffset;
  1653. NdrComplexArrayBufferSize( pStubMsg,
  1654. pMemory,
  1655. pFormat );
  1656. // Pointer increment including alignments.
  1657. BufferLenOffset = pStubMsg->BufferLength - BufferLenOffset;
  1658. //
  1659. // This is the buffer pointer to the position where embedded pointers
  1660. // will be marshalled.
  1661. //
  1662. pStubMsg->PointerBufferMark = pStubMsg->Buffer + BufferLenOffset;
  1663. pStubMsg->BufferLength = BufferLengthSave;
  1664. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1665. // Restore conformance and variance fields.
  1666. pStubMsg->MaxCount = MaxCountSave;
  1667. pStubMsg->Offset = Offset;
  1668. pStubMsg->ActualCount = ActualCount;
  1669. }
  1670. if ( ( *((long UNALIGNED *)(pFormat + 4)) != 0xffffffff ) &&
  1671. ( pStubMsg->pArrayInfo == 0 ) )
  1672. {
  1673. //
  1674. // Outer most dimension sets the conformance marker.
  1675. //
  1676. // Align the buffer for conformance marshalling.
  1677. ALIGN(pStubMsg->Buffer,3);
  1678. // Mark where the conformance count(s) will be marshalled.
  1679. pStubMsg->BufferMark = pStubMsg->Buffer;
  1680. // Increment past where the conformance will go.
  1681. pStubMsg->Buffer += NdrpArrayDimensions( pStubMsg, pFormat, FALSE ) * 4;
  1682. }
  1683. // Call the private marshalling routine to do all the work.
  1684. NdrpComplexArrayMarshall( pStubMsg,
  1685. pMemory,
  1686. pFormat );
  1687. if ( fSetPointerBufferMark )
  1688. {
  1689. //
  1690. // This will set the buffer pointer to end of all of the array's
  1691. // unmarshalled data in the buffer.
  1692. //
  1693. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  1694. pStubMsg->PointerBufferMark = 0;
  1695. }
  1696. return 0;
  1697. }
  1698. void
  1699. NdrpComplexArrayMarshall(
  1700. PMIDL_STUB_MESSAGE pStubMsg,
  1701. uchar * pMemory,
  1702. PFORMAT_STRING pFormat )
  1703. /*++
  1704. Routine Description :
  1705. Private routine for marshalling a complex array. This is the entry
  1706. point for marshalling an embedded complex array.
  1707. Used for FC_BOGUS_ARRAY.
  1708. Arguments :
  1709. pStubMsg - Pointer to the stub message.
  1710. pMemory - Pointer to the array being marshalled.
  1711. pFormat - Array's format string description.
  1712. pStubMsg->Buffer - array pointer
  1713. pStubMsg->BufferMark - a place to marshal the conformant size
  1714. pStubMsg->BufferPointerMark - a place to marshal the pointees
  1715. Return :
  1716. None.
  1717. --*/
  1718. {
  1719. ARRAY_INFO ArrayInfo;
  1720. PARRAY_INFO pArrayInfo;
  1721. PMARSHALL_ROUTINE pfnMarshall;
  1722. PFORMAT_STRING pFormatStart;
  1723. uint Elements;
  1724. uint Offset, Count;
  1725. uint MemoryElementSize;
  1726. long Dimension;
  1727. uchar Alignment;
  1728. bool UseBrokenInterfacePointerRep = false;
  1729. //
  1730. // Lots of setup if we are the outer dimension. All this is for
  1731. // multidimensional array support. If we didn't have to worry about
  1732. // Beta2 stub compatability we could this much better.
  1733. //
  1734. //
  1735. if ( ! pStubMsg->pArrayInfo )
  1736. {
  1737. NdrpInitArrayInfo(pStubMsg, &ArrayInfo );
  1738. }
  1739. pFormatStart = pFormat;
  1740. pArrayInfo = pStubMsg->pArrayInfo;
  1741. Dimension = pArrayInfo->Dimension;
  1742. // Get the array's alignment.
  1743. Alignment = pFormat[1];
  1744. pFormat += 2;
  1745. // Get number of elements (0 if the array has conformance).
  1746. Elements = *((ushort *&)pFormat)++;
  1747. //
  1748. // Check for conformance description.
  1749. //
  1750. if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
  1751. {
  1752. Elements = (ulong) NdrpComputeConformance( pStubMsg,
  1753. pMemory,
  1754. pFormatStart );
  1755. // Marshall this dimension's conformance count.
  1756. pArrayInfo->BufferConformanceMark[Dimension] = Elements;
  1757. }
  1758. pFormat += 4;
  1759. CORRELATION_DESC_INCREMENT( pFormat );
  1760. //
  1761. // Check for variance description.
  1762. //
  1763. if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
  1764. {
  1765. if ( Dimension == 0 )
  1766. {
  1767. //
  1768. // Set the variance marker.
  1769. //
  1770. ALIGN(pStubMsg->Buffer,0x3);
  1771. // Mark where the variance count(s) will be marshalled.
  1772. pArrayInfo->BufferVarianceMark = (unsigned long *) pStubMsg->Buffer;
  1773. // Increment past where the variance will go.
  1774. pStubMsg->Buffer +=
  1775. NdrpArrayDimensions( pStubMsg, pFormatStart, TRUE ) * 8;
  1776. }
  1777. NdrpComputeVariance( pStubMsg,
  1778. pMemory,
  1779. pFormatStart );
  1780. Offset = pStubMsg->Offset;
  1781. Count = pStubMsg->ActualCount;
  1782. //
  1783. // Marshall the outer dimension's variance.
  1784. //
  1785. pArrayInfo->BufferVarianceMark[Dimension * 2] = Offset;
  1786. pArrayInfo->BufferVarianceMark[(Dimension * 2) + 1] = Count;
  1787. }
  1788. else
  1789. {
  1790. Offset = 0;
  1791. Count = Elements;
  1792. }
  1793. pFormat += 4;
  1794. CORRELATION_DESC_INCREMENT( pFormat );
  1795. //
  1796. // Return if count is 0.
  1797. //
  1798. if ( ! Count )
  1799. goto ComplexArrayMarshallEnd;
  1800. // Align on array's alignment.
  1801. ZeroOutGapAndAlign(pStubMsg,Alignment);
  1802. switch ( *pFormat )
  1803. {
  1804. case FC_EMBEDDED_COMPLEX :
  1805. pFormat += 2;
  1806. pFormat += *((signed short *)pFormat);
  1807. if ( FC_IP == *pFormat )
  1808. goto HandleInterfacePointer;
  1809. // Get the proper marshalling routine.
  1810. pfnMarshall = pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)];
  1811. pArrayInfo->Dimension = Dimension + 1;
  1812. // Compute the size of an array element.
  1813. MemoryElementSize = (uint) (NdrpMemoryIncrement( pStubMsg,
  1814. pMemory,
  1815. pFormat ) - pMemory);
  1816. break;
  1817. case FC_RP :
  1818. case FC_UP :
  1819. case FC_FP :
  1820. case FC_OP :
  1821. pfnMarshall = (PMARSHALL_ROUTINE) NdrpPointerMarshall;
  1822. // Need this in case we have a variant offset.
  1823. MemoryElementSize = PTR_MEM_SIZE;
  1824. break;
  1825. case FC_IP :
  1826. HandleInterfacePointer:
  1827. UseBrokenInterfacePointerRep = !FixWireRepForDComVerGTE54( pStubMsg );
  1828. // Probably does not exercise this code path, for IP the compiler
  1829. // generates embedded complex as an array element.
  1830. //
  1831. pfnMarshall = (PMARSHALL_ROUTINE) NdrpPointerMarshall;
  1832. // Need this in case we have a variant offset.
  1833. MemoryElementSize = PTR_MEM_SIZE;
  1834. break;
  1835. case FC_ENUM16 :
  1836. pfnMarshall = 0;
  1837. // Need this in case we have a variant offset.
  1838. MemoryElementSize = sizeof(int);
  1839. break;
  1840. #if defined(__RPC_WIN64__)
  1841. case FC_INT3264:
  1842. case FC_UINT3264:
  1843. pfnMarshall = 0;
  1844. MemoryElementSize = sizeof(__int64);
  1845. break;
  1846. #endif
  1847. case FC_RANGE:
  1848. // let's just memcpy in marshalling phase: don't need to check value here.
  1849. Count *= SIMPLE_TYPE_BUFSIZE( pFormat[1] );
  1850. pMemory += Offset * SIMPLE_TYPE_MEMSIZE( pFormat[1] );
  1851. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1852. pMemory,
  1853. Count );
  1854. pStubMsg->Buffer += Count;
  1855. break;
  1856. default :
  1857. NDR_ASSERT( IS_SIMPLE_TYPE(*pFormat),
  1858. "NdrpComplexArrayMarshall : bad format char" );
  1859. Count *= SIMPLE_TYPE_BUFSIZE(*pFormat);
  1860. pMemory += Offset * SIMPLE_TYPE_MEMSIZE(*pFormat);
  1861. // Copy the array.
  1862. RpcpMarshalMemoryCopy( pStubMsg->Buffer,
  1863. pMemory,
  1864. Count );
  1865. pStubMsg->Buffer += Count;
  1866. goto ComplexArrayMarshallEnd;
  1867. }
  1868. //
  1869. // If there is variance then increment the memory pointer to the first
  1870. // element actually being marshalled.
  1871. //
  1872. if ( Offset )
  1873. pMemory += Offset * MemoryElementSize;
  1874. //
  1875. // Array of enum16 or int3264.
  1876. //
  1877. if ( ! pfnMarshall )
  1878. {
  1879. #if defined(__RPC_WIN64__)
  1880. if ( *pFormat != FC_ENUM16 )
  1881. {
  1882. for ( ; Count--; )
  1883. *((long * &)pStubMsg->Buffer)++ = (long)*((INT64 * &)pMemory)++;
  1884. }
  1885. else
  1886. #endif
  1887. {
  1888. for ( ; Count--; )
  1889. {
  1890. if ( *((int *)pMemory) & ~((int)0x7fff) )
  1891. RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  1892. *((ushort *&)pStubMsg->Buffer)++ = (ushort) *((int *&)pMemory)++;
  1893. }
  1894. }
  1895. goto ComplexArrayMarshallEnd;
  1896. }
  1897. //
  1898. // For 32b, an array of ref or interface pointers.
  1899. // For 64b, an array of any pointers.
  1900. //
  1901. if ( pfnMarshall == (PMARSHALL_ROUTINE) NdrpPointerMarshall )
  1902. {
  1903. pStubMsg->pArrayInfo = 0;
  1904. uchar * pPointerId = (*pFormat == FC_RP) ? 0 : pStubMsg->Buffer;
  1905. if ( UseBrokenInterfacePointerRep )
  1906. {
  1907. // If were using the broken array format, do no increment the
  1908. // buffer pointer for the flat part, and throw everything
  1909. // where the pointee should go.
  1910. SET_BROKEN_INTERFACE_POINTER( pStubMsg->uFlags );
  1911. POINTER_BUFFER_SWAP_CONTEXT NewContext(pStubMsg);
  1912. for ( ; Count--; )
  1913. {
  1914. // This effectively calls NdrInterfacePointerMarshall. Doinging
  1915. // this so another queue structure/callback isn't needed just for
  1916. // this rare code.
  1917. NdrpPointerMarshall(
  1918. pStubMsg,
  1919. pPointerId,
  1920. *((uchar **&)pMemory)++,
  1921. pFormat );
  1922. pPointerId += PTR_WIRE_SIZE;
  1923. }
  1924. RESET_BROKEN_INTERFACE_POINTER( pStubMsg->uFlags );
  1925. }
  1926. else
  1927. {
  1928. {
  1929. POINTER_BUFFER_SWAP_CONTEXT NewContext(pStubMsg);
  1930. for ( ; Count--; )
  1931. {
  1932. NdrpPointerMarshall(
  1933. pStubMsg,
  1934. pPointerId,
  1935. *((uchar **&)pMemory)++,
  1936. pFormat );
  1937. //
  1938. // Needed only for non ref pointers, but pPointerIds is not used for refs.
  1939. //
  1940. pPointerId += PTR_WIRE_SIZE;
  1941. }
  1942. }
  1943. // Increment buffer pointer past the flat part of the array.
  1944. if ( *pFormat != FC_RP )
  1945. pStubMsg->Buffer = pPointerId;
  1946. }
  1947. goto ComplexArrayMarshallEnd;
  1948. }
  1949. //
  1950. // It's an array of complex types.
  1951. //
  1952. if ( ! IS_ARRAY_OR_STRING(*pFormat) )
  1953. pStubMsg->pArrayInfo = 0;
  1954. // Marshall the array elements.
  1955. for ( ; Count--; )
  1956. {
  1957. // Keep track of multidimensional array dimension.
  1958. if ( IS_ARRAY_OR_STRING(*pFormat) )
  1959. pArrayInfo->Dimension = Dimension + 1;
  1960. (*pfnMarshall)( pStubMsg,
  1961. pMemory,
  1962. pFormat );
  1963. // Increment the memory pointer by the element size.
  1964. pMemory += MemoryElementSize;
  1965. }
  1966. ComplexArrayMarshallEnd:
  1967. // pArrayInfo must be zero when not valid.
  1968. pStubMsg->pArrayInfo = (Dimension == 0) ? 0 : pArrayInfo;
  1969. }
  1970. unsigned char * RPC_ENTRY
  1971. NdrEncapsulatedUnionMarshall (
  1972. PMIDL_STUB_MESSAGE pStubMsg,
  1973. uchar * pMemory,
  1974. PFORMAT_STRING pFormat )
  1975. /*++
  1976. Routine Description :
  1977. Marshalls an encapsulated union.
  1978. Used for FC_ENCAPSULATED_UNION.
  1979. Arguments :
  1980. pStubMsg - Pointer to the stub message.
  1981. pMemory - Pointer to the union being marshalled.
  1982. pFormat - Union's format string description.
  1983. Return :
  1984. None.
  1985. --*/
  1986. {
  1987. long SwitchIs;
  1988. uchar SwitchType;
  1989. NO_CORRELATION;
  1990. SwitchType = LOW_NIBBLE(pFormat[1]);
  1991. switch ( SwitchType )
  1992. {
  1993. case FC_SMALL :
  1994. case FC_CHAR :
  1995. SwitchIs = (long) *((char *)pMemory);
  1996. break;
  1997. case FC_USMALL :
  1998. SwitchIs = (long) *((uchar *)pMemory);
  1999. break;
  2000. case FC_ENUM16 :
  2001. case FC_SHORT :
  2002. SwitchIs = (long) *((short *)pMemory);
  2003. break;
  2004. case FC_USHORT :
  2005. case FC_WCHAR :
  2006. SwitchIs = (long) *((ushort *)pMemory);
  2007. break;
  2008. case FC_LONG :
  2009. case FC_ULONG :
  2010. case FC_ENUM32 :
  2011. // FC_INT3264 gets mapped to FC_LONG
  2012. SwitchIs = *((long *)pMemory);
  2013. break;
  2014. default :
  2015. NDR_ASSERT(0,"NdrEncapsulatedUnionMarshall : bad swith type");
  2016. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  2017. return 0;
  2018. }
  2019. // Increment the memory pointer to the union.
  2020. pMemory += HIGH_NIBBLE(pFormat[1]);
  2021. NdrpUnionMarshall( pStubMsg,
  2022. pMemory,
  2023. pFormat + 2,
  2024. SwitchIs,
  2025. SwitchType );
  2026. return 0;
  2027. }
  2028. unsigned char * RPC_ENTRY
  2029. NdrNonEncapsulatedUnionMarshall (
  2030. PMIDL_STUB_MESSAGE pStubMsg,
  2031. uchar * pMemory,
  2032. PFORMAT_STRING pFormat )
  2033. /*++
  2034. Routine Description :
  2035. Marshalls a non encapsulated union.
  2036. Used for FC_NON_ENCAPSULATED_UNION.
  2037. Arguments :
  2038. pStubMsg - Pointer to the stub message.
  2039. pMemory - Pointer to the union being marshalled.
  2040. pFormat - Union's format string description.
  2041. Return :
  2042. None.
  2043. --*/
  2044. {
  2045. long SwitchIs;
  2046. uchar SwitchType;
  2047. SwitchType = pFormat[1];
  2048. SwitchIs = (ulong) NdrpComputeSwitchIs( pStubMsg,
  2049. pMemory,
  2050. pFormat );
  2051. //
  2052. // Set the format string to the memory size and arm description.
  2053. //
  2054. pFormat += 6;
  2055. CORRELATION_DESC_INCREMENT( pFormat );
  2056. pFormat += *((signed short *)pFormat);
  2057. NdrpUnionMarshall( pStubMsg,
  2058. pMemory,
  2059. pFormat,
  2060. SwitchIs,
  2061. SwitchType );
  2062. return 0;
  2063. }
  2064. void
  2065. NdrpUnionMarshall (
  2066. PMIDL_STUB_MESSAGE pStubMsg,
  2067. uchar * pMemory,
  2068. PFORMAT_STRING pFormat,
  2069. long SwitchIs,
  2070. uchar SwitchType )
  2071. /*++
  2072. Routine Description :
  2073. Private routine for marshalling a union. This routine is shared for
  2074. both encapsulated and non-encapsulated unions and handles the actual
  2075. marshalling of the proper union arm.
  2076. Arguments :
  2077. pStubMsg - Pointer to the stub message.
  2078. pMemory - Pointer to the union being marshalled.
  2079. pFormat - The memory size and arm description portion of the format
  2080. string for the union.
  2081. SwitchIs - Union's switch is.
  2082. SwitchType - Union's switch is type.
  2083. Return :
  2084. None.
  2085. --*/
  2086. {
  2087. long Arms;
  2088. uchar Alignment;
  2089. // Marshall the switch is value.
  2090. NdrSimpleTypeMarshall( pStubMsg,
  2091. (uchar *)&SwitchIs,
  2092. SwitchType );
  2093. // Skip the memory size field.
  2094. pFormat += 2;
  2095. //
  2096. // We're at the union_arms<2> field now, which contains both the
  2097. // Microsoft union aligment value and the number of union arms.
  2098. //
  2099. //
  2100. // Get the union alignment (0 if this is a DCE union).
  2101. //
  2102. Alignment = (uchar) ( *((ushort *)pFormat) >> 12 );
  2103. ZeroOutGapAndAlign(pStubMsg,Alignment);
  2104. //
  2105. // Number of arms is the lower 12 bits.
  2106. //
  2107. Arms = (long) ( *((ushort *&)pFormat)++ & 0x0fff);
  2108. //
  2109. // Search for the correct arm.
  2110. //
  2111. for ( ; Arms; Arms-- )
  2112. {
  2113. if ( *((long UNALIGNED *&)pFormat)++ == SwitchIs )
  2114. {
  2115. //
  2116. // Found the right arm, break out.
  2117. //
  2118. break;
  2119. }
  2120. // Else increment format string.
  2121. pFormat += 2;
  2122. }
  2123. //
  2124. // Check if we took the default arm and no default arm is specified.
  2125. //
  2126. if ( ! Arms && (*((ushort *)pFormat) == (ushort) 0xffff) )
  2127. {
  2128. RpcRaiseException( RPC_S_INVALID_TAG );
  2129. }
  2130. //
  2131. // Return if the arm is empty.
  2132. //
  2133. if ( ! *((ushort *)pFormat) )
  2134. return;
  2135. //
  2136. // Get the arm's description.
  2137. //
  2138. // We need a real solution after beta for simple type arms. This could
  2139. // break if we have a format string larger than about 32K.
  2140. //
  2141. if ( IS_MAGIC_UNION_BYTE(pFormat) )
  2142. {
  2143. NdrSimpleTypeMarshall( pStubMsg,
  2144. pMemory,
  2145. pFormat[0] );
  2146. return;
  2147. }
  2148. pFormat += *((signed short *)pFormat);
  2149. //
  2150. // If the union arm we take is a pointer, we have to dereference the
  2151. // current memory pointer since we're passed a pointer to the union
  2152. // (regardless of whether the actual parameter was a by-value union
  2153. // or a pointer to a union).
  2154. //
  2155. // We also have to do a bunch of other special stuff to handle unions
  2156. // embedded inside of strutures.
  2157. //
  2158. if ( IS_POINTER_TYPE(*pFormat) )
  2159. {
  2160. pMemory = *((uchar **)pMemory);
  2161. //
  2162. // If we're embedded in a struct or array we have do some extra stuff.
  2163. //
  2164. if ( pStubMsg->PointerBufferMark )
  2165. {
  2166. ALIGN(pStubMsg->Buffer,3);
  2167. uchar *pPointerId = pStubMsg->Buffer;
  2168. pStubMsg->Buffer += PTR_WIRE_SIZE;
  2169. POINTER_BUFFER_SWAP_CONTEXT SwapContext( pStubMsg );
  2170. NdrpPointerMarshall( pStubMsg,
  2171. pPointerId,
  2172. pMemory,
  2173. pFormat );
  2174. return;
  2175. }
  2176. }
  2177. //
  2178. // Union arm of a non-simple type.
  2179. //
  2180. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)])
  2181. ( pStubMsg,
  2182. pMemory,
  2183. pFormat );
  2184. }
  2185. unsigned char * RPC_ENTRY
  2186. NdrByteCountPointerMarshall (
  2187. PMIDL_STUB_MESSAGE pStubMsg,
  2188. uchar * pMemory,
  2189. PFORMAT_STRING pFormat )
  2190. /*++
  2191. Routine Description :
  2192. Marshalls a pointer with the byte count attribute applied to it.
  2193. Used for FC_BYTE_COUNT_POINTER.
  2194. Arguments :
  2195. pStubMsg - Pointer to the stub message.
  2196. pMemory - Pointer to the byte count pointer being marshalled.
  2197. pFormat - Byte count pointer's format string description.
  2198. Return :
  2199. None.
  2200. --*/
  2201. {
  2202. //
  2203. // We don't do anything special here. Just pass things on to the
  2204. // right marshalling routine.
  2205. //
  2206. if ( pFormat[1] != FC_PAD )
  2207. {
  2208. NdrSimpleTypeMarshall( pStubMsg,
  2209. pMemory,
  2210. pFormat[1] );
  2211. }
  2212. else
  2213. {
  2214. pFormat += 6;
  2215. CORRELATION_DESC_INCREMENT( pFormat );
  2216. pFormat += *((signed short *)pFormat);
  2217. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  2218. pMemory,
  2219. pFormat );
  2220. }
  2221. return 0;
  2222. }
  2223. unsigned char * RPC_ENTRY
  2224. NdrXmitOrRepAsMarshall (
  2225. PMIDL_STUB_MESSAGE pStubMsg,
  2226. uchar * pMemory,
  2227. PFORMAT_STRING pFormat )
  2228. /*++
  2229. Routine Description :
  2230. Marshalls a transmit as or represent as argument:
  2231. - translate the presented object into a transmitted object
  2232. - marshall the transmitted object
  2233. - free the transmitted object
  2234. Format string layout:
  2235. 0 FC_TRANSMIT_AS or FC_REPRESENT_AS
  2236. Oi array flag/alignment<1>
  2237. +2 quintuple index<2>
  2238. +4 pres type mem size<2>
  2239. +6 tran type buf size<2>
  2240. +8 offset<2>
  2241. Arguments :
  2242. pStubMsg - a pointer to the stub message
  2243. pMemory - presented type translated into transmitted type
  2244. and than to be marshalled
  2245. pFormat - format string description
  2246. --*/
  2247. {
  2248. unsigned char * pTransmittedType;
  2249. const XMIT_ROUTINE_QUINTUPLE * pQuintuple = pStubMsg->StubDesc->aXmitQuintuple;
  2250. unsigned short QIndex;
  2251. BOOL fXmitByPtr = *pFormat == FC_TRANSMIT_AS_PTR ||
  2252. *pFormat == FC_REPRESENT_AS_PTR;
  2253. // Skip the token itself and Oi flag. Fetch the QuintupleIndex.
  2254. QIndex = *(unsigned short *)(pFormat + 2);
  2255. // First translate the presented type into the transmitted type.
  2256. // This includes an allocation of a transmitted type object.
  2257. pStubMsg->pPresentedType = pMemory;
  2258. pStubMsg->pTransmitType = NULL;
  2259. pQuintuple[ QIndex ].pfnTranslateToXmit( pStubMsg );
  2260. // Marshall the transmitted type.
  2261. pFormat += 8;
  2262. pFormat = pFormat + *(short *) pFormat;
  2263. pTransmittedType = pStubMsg->pTransmitType;
  2264. if ( IS_SIMPLE_TYPE( *pFormat ))
  2265. {
  2266. NdrSimpleTypeMarshall( pStubMsg,
  2267. pTransmittedType,
  2268. *pFormat );
  2269. }
  2270. else
  2271. {
  2272. uchar *PointerBufferMarkSave = pStubMsg->PointerBufferMark;
  2273. pStubMsg->PointerBufferMark = 0;
  2274. NDR_POINTER_QUEUE *pOldQueue = NULL;
  2275. // Reset the current queue to NULL so that all the pointers
  2276. // in the transmitted type will be queued and marshalled togother.
  2277. if ( pStubMsg->pPointerQueueState )
  2278. {
  2279. pOldQueue = pStubMsg->pPointerQueueState->GetActiveQueue();
  2280. pStubMsg->pPointerQueueState->SetActiveQueue(NULL);
  2281. }
  2282. RpcTryFinally
  2283. {
  2284. (*pfnMarshallRoutines[ROUTINE_INDEX(*pFormat)])
  2285. ( pStubMsg,
  2286. fXmitByPtr ? *(uchar **)pTransmittedType
  2287. : pTransmittedType,
  2288. pFormat );
  2289. }
  2290. RpcFinally
  2291. {
  2292. pStubMsg->PointerBufferMark = PointerBufferMarkSave;
  2293. if ( pStubMsg->pPointerQueueState )
  2294. {
  2295. pStubMsg->pPointerQueueState->SetActiveQueue( pOldQueue );
  2296. }
  2297. }
  2298. RpcEndFinally
  2299. }
  2300. pStubMsg->pTransmitType = pTransmittedType;
  2301. // Free the temporary transmitted object (it was allocated by the user).
  2302. pQuintuple[ QIndex ].pfnFreeXmit( pStubMsg );
  2303. return 0;
  2304. }
  2305. void
  2306. NdrpUserMarshalMarshall(
  2307. PMIDL_STUB_MESSAGE pStubMsg,
  2308. uchar * pMemory,
  2309. PFORMAT_STRING pFormat,
  2310. unsigned long * pWireMarkerPtr )
  2311. /*++
  2312. Routine Description :
  2313. Marshals a usr_marshall object.
  2314. The format string layout is as follows:
  2315. FC_USER_MARSHAL
  2316. flags & alignment<1>
  2317. quadruple index<2>
  2318. memory size<2>
  2319. wire size<2>
  2320. type offset<2>
  2321. The wire layout description is at the type offset.
  2322. Arguments :
  2323. pStubMsg - Pointer to the stub message.
  2324. pMemory - Pointer to the usr_marshall object to marshall.
  2325. pFormat - Object's format string description.
  2326. Return :
  2327. None.
  2328. --*/
  2329. {
  2330. const USER_MARSHAL_ROUTINE_QUADRUPLE * pQuadruple;
  2331. unsigned short QIndex;
  2332. unsigned char * pUserBuffer;
  2333. USER_MARSHAL_CB UserMarshalCB;
  2334. unsigned char * pUserBufferSaved;
  2335. pUserBufferSaved = pUserBuffer = pStubMsg->Buffer;
  2336. // We always call user's routine to marshall.
  2337. NdrpInitUserMarshalCB( pStubMsg,
  2338. pFormat,
  2339. USER_MARSHAL_CB_MARSHALL,
  2340. & UserMarshalCB );
  2341. QIndex = *(unsigned short *)(pFormat + 2);
  2342. pQuadruple = pStubMsg->StubDesc->aUserMarshalQuadruple;
  2343. if ((pUserBufferSaved < (uchar *) pStubMsg->RpcMsg->Buffer) ||
  2344. ((unsigned long) (pUserBufferSaved - (uchar *) pStubMsg->RpcMsg->Buffer)
  2345. > pStubMsg->RpcMsg->BufferLength))
  2346. {
  2347. RpcRaiseException( RPC_X_INVALID_BUFFER );
  2348. }
  2349. pUserBuffer = pQuadruple[ QIndex ].pfnMarshall( (ulong*) &UserMarshalCB,
  2350. pUserBuffer,
  2351. pMemory );
  2352. if ((pUserBufferSaved > pUserBuffer) ||
  2353. ((unsigned long) (pUserBuffer - (uchar *) pStubMsg->RpcMsg->Buffer)
  2354. > pStubMsg->RpcMsg->BufferLength ))
  2355. {
  2356. RpcRaiseException( RPC_X_INVALID_BUFFER );
  2357. }
  2358. if ( pUserBuffer == pUserBufferSaved )
  2359. {
  2360. // This is valid only if the wire type was a unique type.
  2361. if ( (pFormat[1] & USER_MARSHAL_UNIQUE) )
  2362. {
  2363. *pWireMarkerPtr = 0;
  2364. return;
  2365. }
  2366. else
  2367. RpcRaiseException( RPC_X_NULL_REF_POINTER );
  2368. }
  2369. pStubMsg->Buffer = pUserBuffer;
  2370. return;
  2371. }
  2372. void
  2373. NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT::Dispatch(MIDL_STUB_MESSAGE *pStubMsg)
  2374. {
  2375. NdrpUserMarshalMarshall( pStubMsg,
  2376. pMemory,
  2377. pFormat,
  2378. pWireMarkerPtr );
  2379. }
  2380. #if defined(DBG)
  2381. void
  2382. NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT::Print()
  2383. {
  2384. DbgPrint("NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT\n");
  2385. DbgPrint("pMemory: %p\n", pMemory );
  2386. DbgPrint("pFormat: %p\n", pFormat );
  2387. DbgPrint("pWireMarkerPtr: %p\n", pWireMarkerPtr );
  2388. }
  2389. #endif
  2390. unsigned char * RPC_ENTRY
  2391. NdrUserMarshalMarshall(
  2392. PMIDL_STUB_MESSAGE pStubMsg,
  2393. uchar * pMemory,
  2394. PFORMAT_STRING pFormat )
  2395. {
  2396. unsigned long * pWireMarkerPtr = 0;
  2397. // Align for the object or a pointer to it.
  2398. ZeroOutGapAndAlign( pStubMsg, LOW_NIBBLE(pFormat[1]) );
  2399. if ( pFormat[1] & USER_MARSHAL_POINTER )
  2400. {
  2401. if ( (pFormat[1] & USER_MARSHAL_UNIQUE) ||
  2402. ((pFormat[1] & USER_MARSHAL_REF) && pStubMsg->PointerBufferMark) )
  2403. {
  2404. pWireMarkerPtr = (unsigned long *) pStubMsg->Buffer;
  2405. *((unsigned long *&)pStubMsg->Buffer)++ = USER_MARSHAL_MARKER;
  2406. }
  2407. if ( !pStubMsg->pPointerQueueState ||
  2408. !pStubMsg->pPointerQueueState->GetActiveQueue() )
  2409. {
  2410. // If we are embedded, switch to the pointee buffer.
  2411. POINTER_BUFFER_SWAP_CONTEXT SwapContext(pStubMsg);
  2412. NdrpUserMarshalMarshall( pStubMsg,
  2413. pMemory,
  2414. pFormat,
  2415. pWireMarkerPtr );
  2416. }
  2417. else
  2418. {
  2419. NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT*pElement =
  2420. new(pStubMsg->pPointerQueueState)
  2421. NDR_USR_MRSHL_MRSHL_POINTER_QUEUE_ELEMENT(pMemory,
  2422. pFormat,
  2423. pWireMarkerPtr);
  2424. pStubMsg->pPointerQueueState->GetActiveQueue()->Enque( pElement );
  2425. }
  2426. return 0;
  2427. }
  2428. NdrpUserMarshalMarshall( pStubMsg,
  2429. pMemory,
  2430. pFormat,
  2431. pWireMarkerPtr );
  2432. return 0;
  2433. }
  2434. unsigned char *
  2435. NdrpInterfacePointerMarshall (
  2436. PMIDL_STUB_MESSAGE pStubMsg,
  2437. uchar * pMemory,
  2438. PFORMAT_STRING pFormat )
  2439. /*++
  2440. Routine Description :
  2441. Marshalls an interface pointer.
  2442. Arguments :
  2443. pStubMsg - Pointer to the stub message.
  2444. pMemory - Pointer to the interface pointer being marshalled.
  2445. pFormat - Interface pointer's format string description.
  2446. Return :
  2447. None.
  2448. Notes : There is now one representation of a marshalled interface pointer.
  2449. The format string contains FC_IP followed by either
  2450. FC_CONSTANT_IID or FC_PAD.
  2451. typedef struct
  2452. {
  2453. unsigned long size;
  2454. [size_is(size)] byte data[];
  2455. }MarshalledInterface;
  2456. --*/
  2457. {
  2458. HRESULT hr;
  2459. IID iid;
  2460. IID * piid;
  2461. unsigned long * pSize;
  2462. unsigned long * pMaxCount;
  2463. unsigned long cbData = 0;
  2464. unsigned long cbMax;
  2465. unsigned long position;
  2466. IStream * pStream;
  2467. LARGE_INTEGER libMove;
  2468. ULARGE_INTEGER libPosition;
  2469. ALIGN(pStubMsg->Buffer,0x3);
  2470. //
  2471. // Get an IID pointer.
  2472. //
  2473. if ( pFormat[1] != FC_CONSTANT_IID )
  2474. {
  2475. //
  2476. // This is like computing a variance with a long.
  2477. //
  2478. piid = (IID *) NdrpComputeIIDPointer( pStubMsg,
  2479. pMemory,
  2480. pFormat );
  2481. if(piid == 0)
  2482. RpcRaiseException( RPC_S_INVALID_ARG );
  2483. }
  2484. else
  2485. {
  2486. //
  2487. // The IID may not be aligned properly in the format string,
  2488. // so we copy it to a local variable.
  2489. //
  2490. // we don't need to zero out the end pad as the size is 16.
  2491. piid = &iid;
  2492. RpcpMemoryCopy( &iid, &pFormat[2], sizeof(iid) );
  2493. }
  2494. // Leave space in the buffer for the conformant size and the size field.
  2495. pMaxCount = (unsigned long *) pStubMsg->Buffer;
  2496. pStubMsg->Buffer += sizeof(unsigned long);
  2497. pSize = (unsigned long *) pStubMsg->Buffer;
  2498. pStubMsg->Buffer += sizeof(unsigned long);
  2499. if(pMemory)
  2500. {
  2501. //Calculate the maximum size of the stream.
  2502. position = (ulong)( pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer);
  2503. cbMax = pStubMsg->RpcMsg->BufferLength - position;
  2504. //Create a stream on memory.
  2505. pStream = NdrpCreateStreamOnMemory(pStubMsg->Buffer, cbMax);
  2506. if(pStream == 0)
  2507. RpcRaiseException(RPC_S_OUT_OF_MEMORY);
  2508. hr = (*pfnCoMarshalInterface)(pStream, *piid, (IUnknown *)pMemory, pStubMsg->dwDestContext, pStubMsg->pvDestContext, 0);
  2509. if(FAILED(hr))
  2510. {
  2511. pStream->Release();
  2512. pStream = 0;
  2513. RpcRaiseException(hr);
  2514. }
  2515. //Calculate the size of the data written
  2516. libMove.LowPart = 0;
  2517. libMove.HighPart = 0;
  2518. pStream->Seek(libMove, STREAM_SEEK_CUR, &libPosition);
  2519. pStream->Release();
  2520. pStream = 0;
  2521. cbData = libPosition.LowPart;
  2522. }
  2523. //Update the array bounds.
  2524. *pMaxCount = cbData;
  2525. *pSize = cbData;
  2526. //Advance the stub message buffer pointer.
  2527. pStubMsg->Buffer += cbData;
  2528. return 0;
  2529. }
  2530. unsigned char * RPC_ENTRY
  2531. NdrInterfacePointerMarshall (
  2532. PMIDL_STUB_MESSAGE pStubMsg,
  2533. uchar * pMemory,
  2534. PFORMAT_STRING pFormat )
  2535. {
  2536. // Always put the pointer itself on wire, it behaves like a unique.
  2537. //
  2538. // This function is only called for toplevel interface pointers with Os mode,
  2539. // or when being backward compatible with the incorrect wire format.
  2540. // Oicf uses NdrPointerMarshall.
  2541. ALIGN(pStubMsg->Buffer,0x3);
  2542. *((ulong *&)pStubMsg->Buffer)++ = PTR_WIRE_REP(pMemory, pStubMsg );
  2543. // If the pointer is null, it's done.
  2544. if ( pMemory == 0 )
  2545. return 0;
  2546. return
  2547. NdrpInterfacePointerMarshall(
  2548. pStubMsg,
  2549. pMemory,
  2550. pFormat );
  2551. }
  2552. //
  2553. // Context handle marshalling routines.
  2554. //
  2555. void RPC_ENTRY
  2556. NdrClientContextMarshall(
  2557. PMIDL_STUB_MESSAGE pStubMsg,
  2558. NDR_CCONTEXT ContextHandle,
  2559. int fCheck )
  2560. /*++
  2561. Routine Description :
  2562. Marshalls a context handle on the client side.
  2563. Arguments :
  2564. pStubMsg - Pointer to stub message.
  2565. ContextHandle - Context handle to marshall.
  2566. fCheck - TRUE if an exception check should be made on the handle,
  2567. FALSE otherwise.
  2568. Return :
  2569. None.
  2570. --*/
  2571. {
  2572. // Note, this is a routine called directly from -Os stubs.
  2573. // The routine called by interpreter is called NdrMarshallHandle
  2574. // and can be found in hndl.c
  2575. if ( fCheck && ! ContextHandle )
  2576. RpcRaiseException( RPC_X_SS_IN_NULL_CONTEXT );
  2577. ALIGN(pStubMsg->Buffer,3);
  2578. // This call will check for bogus handles now and will raise
  2579. // an exception when necessary.
  2580. NDRCContextMarshall( ContextHandle, pStubMsg->Buffer );
  2581. pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE;
  2582. }
  2583. void RPC_ENTRY
  2584. NdrServerContextMarshall(
  2585. PMIDL_STUB_MESSAGE pStubMsg,
  2586. NDR_SCONTEXT ContextHandle,
  2587. NDR_RUNDOWN RundownRoutine )
  2588. /*++
  2589. Routine Description :
  2590. Marshalls a context handle on the server side.
  2591. Arguments :
  2592. pStubMsg - Pointer to stub message.
  2593. ContextHandle - Context handle to marshall.
  2594. RundownRoutine - The context rundown routine.
  2595. Return :
  2596. None.
  2597. --*/
  2598. {
  2599. // Note, this is a routine called directly from -Os stubs.
  2600. // The routine called by interpreter is called NdrMarshallHandle
  2601. // and can be found in hndl.c
  2602. ALIGN(pStubMsg->Buffer,3);
  2603. NDRSContextMarshall2(pStubMsg->RpcMsg->Handle,
  2604. ContextHandle,
  2605. pStubMsg->Buffer,
  2606. RundownRoutine,
  2607. RPC_CONTEXT_HANDLE_DEFAULT_GUARD,
  2608. RPC_CONTEXT_HANDLE_DEFAULT_FLAGS );
  2609. pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE;
  2610. }
  2611. void RPC_ENTRY
  2612. NdrServerContextNewMarshall(
  2613. PMIDL_STUB_MESSAGE pStubMsg,
  2614. NDR_SCONTEXT ContextHandle,
  2615. NDR_RUNDOWN RundownRoutine,
  2616. PFORMAT_STRING pFormat )
  2617. /*
  2618. This is a non-optimized NDR engine entry for context handle marshaling.
  2619. In particular it is able to handle all the new NT5 context handle flavors.
  2620. The optimized routine follows below.
  2621. ContextHandle - note, this is not the user's handle but a
  2622. NDR_SCONTEXT pointer from the stub local stack.
  2623. User's handle is a field in that object.
  2624. Note that intepreter calls NdrMarshallHandle. However, we can't use it
  2625. as it assumes a helper array of saved context handles that we don't need.
  2626. */
  2627. {
  2628. void * pGuard = RPC_CONTEXT_HANDLE_DEFAULT_GUARD;
  2629. DWORD Flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
  2630. // NT5 beta2 features: strict context handle, serialize and noserialize.
  2631. if ( pFormat[1] & NDR_STRICT_CONTEXT_HANDLE )
  2632. {
  2633. pGuard = pStubMsg->StubDesc->RpcInterfaceInformation;
  2634. pGuard = & ((PRPC_SERVER_INTERFACE)pGuard)->InterfaceId;
  2635. }
  2636. if ( pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE )
  2637. {
  2638. Flags = RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
  2639. }
  2640. else if ( pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE )
  2641. {
  2642. Flags = RPC_CONTEXT_HANDLE_SERIALIZE;
  2643. }
  2644. ALIGN( pStubMsg->Buffer, 0x3 );
  2645. NDRSContextMarshall2(
  2646. pStubMsg->RpcMsg->Handle,
  2647. ContextHandle,
  2648. pStubMsg->Buffer,
  2649. RundownRoutine,
  2650. pGuard,
  2651. Flags );
  2652. pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE;
  2653. }
  2654. void
  2655. NdrpGetArraySizeLength (
  2656. PMIDL_STUB_MESSAGE pStubMsg,
  2657. uchar * pMemory,
  2658. PFORMAT_STRING pFormat,
  2659. long ElementSize,
  2660. long * pSize,
  2661. long * pLength,
  2662. long * pWireSize )
  2663. /*++
  2664. Routine Description :
  2665. Return the size and length of an array.
  2666. We need to have this routine rather than just calling BufferSize since
  2667. we need the actual length of the array, not the length plus whatever
  2668. goop the NDR format puts in from of it.
  2669. Arguments :
  2670. pStubMsg - Pointer to the stub message.
  2671. pMemory - Pointer to the local array.
  2672. pFormat - Pointer to the array to get the size of.
  2673. Return :
  2674. The size and length.
  2675. Notes:
  2676. --*/
  2677. {
  2678. switch ( *pFormat )
  2679. {
  2680. case FC_SMFARRAY:
  2681. *pWireSize = * (short *) ( pFormat + 2 );
  2682. *pSize = *pWireSize;
  2683. *pLength = *pSize;
  2684. return;
  2685. case FC_LGFARRAY:
  2686. *pWireSize = * (int *) ( pFormat + 2 );
  2687. *pSize = *pWireSize;
  2688. *pLength = *pSize;
  2689. return;
  2690. case FC_CARRAY:
  2691. *pSize = (long) NdrpComputeConformance( pStubMsg, pMemory, pFormat );
  2692. *pWireSize = *pLength * ElementSize;
  2693. *pLength = *pSize;
  2694. return;
  2695. case FC_LGVARRAY:
  2696. *pWireSize = * (long *) ( pFormat + 2 );
  2697. *pSize = * (short *) ( pFormat + 6 );
  2698. NdrpComputeVariance( pStubMsg, pMemory, pFormat );
  2699. *pLength = pStubMsg->ActualCount;
  2700. return;
  2701. case FC_SMVARRAY:
  2702. *pWireSize = * (short *) ( pFormat + 2 );
  2703. *pSize = * (short *) ( pFormat + 4 );
  2704. NdrpComputeVariance( pStubMsg, pMemory, pFormat );
  2705. *pLength = pStubMsg->ActualCount;
  2706. return;
  2707. case FC_CVARRAY:
  2708. *pSize = (long) NdrpComputeConformance( pStubMsg, pMemory, pFormat );
  2709. *pWireSize = *pSize * ElementSize;
  2710. NdrpComputeVariance( pStubMsg, pMemory, pFormat );
  2711. *pLength = pStubMsg->ActualCount;
  2712. return;
  2713. case FC_CSTRING:
  2714. *pSize = strlen( (char*)pMemory ) + 1;
  2715. *pWireSize = *pSize;
  2716. *pLength = *pSize;
  2717. return;
  2718. case FC_WSTRING:
  2719. *pSize = wcslen( (wchar_t *) pMemory ) + 1;
  2720. *pWireSize = *pSize * 2;
  2721. *pLength = *pSize;
  2722. return;
  2723. }
  2724. NDR_ASSERT( 0, "NdrpGetArraySizeLength: Unhandled type" );
  2725. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  2726. *pSize = 0;
  2727. *pWireSize = 0;
  2728. *pLength = 0;
  2729. }
  2730. #ifdef _CS_CHAR_
  2731. unsigned char * RPC_ENTRY
  2732. NdrCsTagMarshall (
  2733. PMIDL_STUB_MESSAGE pStubMsg,
  2734. uchar * pMemory,
  2735. PFORMAT_STRING pFormat )
  2736. /*++
  2737. Routine Description :
  2738. Marshalls a cs tag (i.e. a parameter marked with [cs_stag], [cs_drtag],
  2739. or [cs_rtag].
  2740. Arguments :
  2741. pStubMsg - Pointer to the stub message.
  2742. pMemory - Pointer to the value on the stack.
  2743. pFormat - Pointer to the FC_CS_TAG entry in the format string.
  2744. Return :
  2745. None.
  2746. --*/
  2747. {
  2748. ulong Codeset = NdrpGetSetCSTagMarshall(
  2749. pStubMsg,
  2750. pMemory,
  2751. (NDR_CS_TAG_FORMAT *) pFormat);
  2752. * (ulong *) pStubMsg->Buffer = Codeset;
  2753. pStubMsg->Buffer += sizeof( ulong );
  2754. return 0;
  2755. }
  2756. extern const byte NdrpArrayMarshallFlags[] =
  2757. {
  2758. MARSHALL_CONFORMANCE, // Conformant array
  2759. MARSHALL_CONFORMANCE | MARSHALL_VARIANCE, // Conformant varying
  2760. 0, // Small fixed
  2761. 0, // Large fixed
  2762. MARSHALL_VARIANCE, // Small varying
  2763. MARSHALL_VARIANCE, // Large varying
  2764. MARSHALL_BOGUS, // Bogus array
  2765. MARSHALL_CONFORMANCE | MARSHALL_VARIANCE, // Conformant C string
  2766. MARSHALL_CONFORMANCE | MARSHALL_VARIANCE, // Conformant byte string
  2767. MARSHALL_CONFORMANCE | MARSHALL_VARIANCE, // Conformant struct string
  2768. MARSHALL_CONFORMANCE | MARSHALL_VARIANCE, // Conformant Unicode string
  2769. MARSHALL_VARIANCE, // C string
  2770. MARSHALL_VARIANCE, // byte string
  2771. MARSHALL_VARIANCE, // struct string
  2772. MARSHALL_VARIANCE // Unicode string
  2773. };
  2774. void
  2775. NdrpUpdateArrayProlog(
  2776. PFORMAT_STRING pFormat,
  2777. uchar * BufferMark,
  2778. ulong WireSize,
  2779. ulong Offset,
  2780. ulong WireLength )
  2781. {
  2782. int flags;
  2783. NDR_ASSERT( *pFormat >= FC_CARRAY, "Invalid array descriptor" );
  2784. NDR_ASSERT( *pFormat <= FC_WSTRING, "Invalid array descriptor" );
  2785. // We don't support bogus arrays for now
  2786. NDR_ASSERT( *pFormat != FC_BOGUS_ARRAY, "Bogus arrays are not supported" );
  2787. flags = NdrpArrayMarshallFlags[ *pFormat - FC_CARRAY ];
  2788. if ( flags & MARSHALL_CONFORMANCE )
  2789. {
  2790. * (ulong *) BufferMark = WireSize;
  2791. BufferMark += 4;
  2792. }
  2793. if ( flags & MARSHALL_VARIANCE )
  2794. {
  2795. * (ulong *) BufferMark = Offset;
  2796. BufferMark += 4;
  2797. * (ulong *) BufferMark = WireLength;
  2798. }
  2799. }
  2800. unsigned char * RPC_ENTRY
  2801. NdrCsArrayMarshall (
  2802. PMIDL_STUB_MESSAGE pStubMsg,
  2803. uchar * pMemory,
  2804. PFORMAT_STRING pFormat )
  2805. /*++
  2806. Routine Description :
  2807. Marshalls a [cs_char] array.
  2808. Arguments :
  2809. pStubMsg - Pointer to the stub message.
  2810. pMemory - Pointer to the local array.
  2811. pFormat - Pointer to the FC_CSARRAY entry in the format string.
  2812. Return :
  2813. None.
  2814. Notes :
  2815. Arrays of [cs_char] are defined as arrays of bytes on the wire so
  2816. marshalling is pretty simple once you know which bytes to marshall and
  2817. how many of them. Since the existing array marshalling routines are not
  2818. very general (they don't take size/length parameters) and since the
  2819. overhead of a call to memcpy isn't very high we do the marshalling
  2820. ourselves.
  2821. --*/
  2822. {
  2823. ulong SendingCodeset;
  2824. ulong ReceivingCodeset;
  2825. ulong ArraySize;
  2826. ulong ArrayLength;
  2827. ulong WireSize;
  2828. ulong WireLength;
  2829. uchar *BufferMark;
  2830. error_status_t status;
  2831. NDR_CS_ARRAY_FORMAT *pCSFormat;
  2832. NDR_CS_SIZE_CONVERT_ROUTINES *CSRoutines;
  2833. CS_TYPE_NET_SIZE_ROUTINE NetSizeRoutine;
  2834. CS_TYPE_TO_NETCS_ROUTINE ToNetCSRoutine;
  2835. IDL_CS_CONVERT ConversionType;
  2836. pCSFormat = (NDR_CS_ARRAY_FORMAT *) pFormat;
  2837. // Get all the info out of the FC_CS_ARRAY structure and bump pFormat
  2838. // to point to the underlying data descriptor
  2839. NDR_ASSERT( NULL != pStubMsg->pCSInfo, "cs_char info is not set up");
  2840. if ( pStubMsg->IsClient )
  2841. SendingCodeset = pStubMsg->pCSInfo->WireCodeset;
  2842. else
  2843. SendingCodeset = pStubMsg->pCSInfo->DesiredReceivingCodeset;
  2844. CSRoutines = pStubMsg->StubDesc->CsRoutineTables->pSizeConvertRoutines;
  2845. NetSizeRoutine = CSRoutines[pCSFormat->CSRoutineIndex].pfnNetSize;
  2846. ToNetCSRoutine = CSRoutines[pCSFormat->CSRoutineIndex].pfnToNetCs;
  2847. pFormat += pCSFormat->DescriptionOffset;
  2848. // Get the size and length of the unconverted array.
  2849. NdrpGetArraySizeLength( pStubMsg,
  2850. pMemory,
  2851. pFormat,
  2852. pCSFormat->UserTypeSize,
  2853. (long*)&ArraySize,
  2854. (long*)&ArrayLength,
  2855. (long*)&WireSize );
  2856. // Figure out whether we need to convert the data
  2857. WireSize = ArraySize;
  2858. NetSizeRoutine(
  2859. pStubMsg->RpcMsg->Handle,
  2860. SendingCodeset,
  2861. ArraySize,
  2862. &ConversionType,
  2863. NdrpIsConformantArray( pFormat ) ? &WireSize : NULL,
  2864. &status);
  2865. if ( RPC_S_OK != status )
  2866. RpcRaiseException( status );
  2867. // Skip the buffer ahead to where the actual bits will go. We'll patch
  2868. // up the array prolog later.
  2869. ALIGN( pStubMsg->Buffer, 3 );
  2870. BufferMark = pStubMsg->Buffer;
  2871. pStubMsg->Buffer += NdrpArrayPrologLength( pFormat );
  2872. // If we need to convert do so, otherwise just memcpy
  2873. // WireLength = WireSize;
  2874. WireLength = ArrayLength * pCSFormat->UserTypeSize;
  2875. if ( IDL_CS_NO_CONVERT == ConversionType )
  2876. {
  2877. CopyMemory( pStubMsg->Buffer, pMemory, WireLength );
  2878. pStubMsg->Buffer += WireLength;
  2879. }
  2880. else
  2881. {
  2882. ToNetCSRoutine(
  2883. pStubMsg->RpcMsg->Handle,
  2884. SendingCodeset,
  2885. pMemory,
  2886. ArrayLength,
  2887. pStubMsg->Buffer,
  2888. // ! NdrpIsVaryingArray( pFormat ) ? NULL : &WireLength,
  2889. NdrpIsFixedArray( pFormat ) ? NULL : &WireLength,
  2890. &status);
  2891. if ( RPC_S_OK != status )
  2892. RpcRaiseException( status );
  2893. NDR_ASSERT(
  2894. WireLength <= WireSize,
  2895. "Buffer overflow during [cs_char] conversion");
  2896. pStubMsg->Buffer += WireLength;
  2897. /*
  2898. // For conformant or fixed arrays we must have WireSize bytes on the
  2899. // wire so pad it out if necessary
  2900. if ( ! NdrpIsVaryingArray( pFormat ) && WireLength < WireSize )
  2901. {
  2902. // REVIEW: Is zero'ing necessary?
  2903. ZeroMemory( pStubMsg->Buffer, WireSize - WireLength );
  2904. pStubMsg->Buffer += WireSize - WireLength;
  2905. }
  2906. */
  2907. if ( ! NdrpIsVaryingArray( pFormat ) )
  2908. WireSize = WireLength;
  2909. }
  2910. NdrpUpdateArrayProlog(
  2911. pFormat,
  2912. BufferMark,
  2913. WireSize,
  2914. pStubMsg->Offset,
  2915. WireLength );
  2916. return 0;
  2917. }
  2918. #endif // _CS_CHAR
  2919. void
  2920. RPC_ENTRY
  2921. NdrPartialIgnoreClientMarshall(
  2922. PMIDL_STUB_MESSAGE pStubMsg,
  2923. void * pMemory
  2924. )
  2925. {
  2926. ALIGN( pStubMsg->Buffer, 0x3 );
  2927. *(ulong *)pStubMsg->Buffer = pMemory ? 1 : 0;
  2928. pStubMsg->Buffer += PTR_WIRE_SIZE;
  2929. }