Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3380 lines
90 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name :
  4. endian.c
  5. Abstract :
  6. This file contains the routines called by MIDL 2.0 stubs and the
  7. interpreter to perform endian, floating pointer, and character conversions.
  8. Author :
  9. David Kays dkays December 1993.
  10. Revision History :
  11. ---------------------------------------------------------------------*/
  12. #include "cvt.h"
  13. #include "ndrp.h"
  14. #include "interp2.h"
  15. #include "attack.h"
  16. void
  17. NdrUDTSimpeTypeConvert(
  18. PMIDL_STUB_MESSAGE pStubMsg,
  19. PFORMAT_STRING pFormat,
  20. uchar fEmbeddedPointerPass );
  21. void cvt_ibm_f_to_ieee_single( ULONG *ulFP );
  22. void cvt_ibm_d_to_ieee_double( ULONG *ulFP );
  23. //
  24. // Conversion routine table.
  25. //
  26. const
  27. PCONVERT_ROUTINE ConvertRoutinesTable[] =
  28. {
  29. NdrUDTSimpeTypeConvert,
  30. NdrUDTSimpeTypeConvert,
  31. NdrUDTSimpeTypeConvert,
  32. NdrUDTSimpeTypeConvert,
  33. NdrUDTSimpeTypeConvert,
  34. NdrUDTSimpeTypeConvert,
  35. NdrUDTSimpeTypeConvert,
  36. NdrUDTSimpeTypeConvert,
  37. NdrUDTSimpeTypeConvert,
  38. NdrUDTSimpeTypeConvert,
  39. NdrUDTSimpeTypeConvert,
  40. NdrUDTSimpeTypeConvert,
  41. NdrUDTSimpeTypeConvert,
  42. NdrUDTSimpeTypeConvert,
  43. NdrUDTSimpeTypeConvert,
  44. NdrUDTSimpeTypeConvert,
  45. NdrUDTSimpeTypeConvert,
  46. NdrPointerConvert,
  47. NdrPointerConvert,
  48. NdrPointerConvert,
  49. NdrPointerConvert,
  50. NdrSimpleStructConvert,
  51. NdrSimpleStructConvert,
  52. NdrConformantStructConvert,
  53. NdrConformantStructConvert,
  54. NdrConformantStructConvert, // same as FC_CARRAY
  55. NdrComplexStructConvert,
  56. NdrConformantArrayConvert,
  57. NdrConformantVaryingArrayConvert,
  58. NdrFixedArrayConvert,
  59. NdrFixedArrayConvert,
  60. NdrVaryingArrayConvert,
  61. NdrVaryingArrayConvert,
  62. NdrComplexArrayConvert,
  63. NdrConformantStringConvert,
  64. NdrConformantStringConvert,
  65. NdrConformantStringConvert,
  66. NdrConformantStringConvert,
  67. NdrNonConformantStringConvert,
  68. NdrNonConformantStringConvert,
  69. NdrNonConformantStringConvert,
  70. NdrNonConformantStringConvert,
  71. NdrEncapsulatedUnionConvert,
  72. NdrNonEncapsulatedUnionConvert,
  73. NdrByteCountPointerConvert,
  74. NdrXmitOrRepAsConvert, // transmit as
  75. NdrXmitOrRepAsConvert, // represent as
  76. NdrInterfacePointerConvert,
  77. NdrContextHandleConvert,
  78. 0, // NdrHardStructConvert,
  79. NdrXmitOrRepAsConvert, // transmit as ptr
  80. NdrXmitOrRepAsConvert, // represent as ptr
  81. NdrUserMarshalConvert,
  82. 0, // FC_PIPE
  83. 0, // FC_BLK_HOLE
  84. NdrpRangeConvert
  85. };
  86. extern const
  87. PCONVERT_ROUTINE * pfnConvertRoutines = ConvertRoutinesTable;
  88. void
  89. NdrUDTSimpeTypeConvert(
  90. PMIDL_STUB_MESSAGE pStubMsg,
  91. PFORMAT_STRING pFormat,
  92. uchar fEmbeddedPointerPass )
  93. {
  94. if ( fEmbeddedPointerPass )
  95. {
  96. ALIGN(pStubMsg->Buffer,SIMPLE_TYPE_ALIGNMENT(*pFormat));
  97. pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE(*pFormat);
  98. }
  99. else
  100. {
  101. NdrSimpleTypeConvert( pStubMsg,
  102. *pFormat );
  103. }
  104. }
  105. //
  106. // Array for ebcdic to ascii conversions. Use ebcdic value as index into
  107. // array whose corresponding value is the correct ascii value.
  108. // The table below maps from IBM 1047 EBCDIC codeset to ANSI 1252 code page.
  109. //
  110. // Note that due to a disagreement among the code page experts both within Msft
  111. // and between Msft and SAG, I could not determine what the proper mapping
  112. // between these 2 code pages should be.
  113. // The following 2 characters where in dispute:
  114. // 0x15 maps to 0x0a - this is most likely right, as per experts' majority vote
  115. // 0x25 maps to 0x85 - no agreement here at all, except that for back mapping
  116. // it cannot be 0x0a again.
  117. // So, I resolved to use the mapping that worked for SAG.
  118. // Ryszardk, Dec 4, 97
  119. //
  120. extern const
  121. unsigned char EbcdicToAscii[] =
  122. {
  123. 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
  124. 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  125. 0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87, // 0x15 -> 0x0a
  126. 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
  127. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b, // 0x25 -> 0x85
  128. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
  129. 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
  130. 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
  131. 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
  132. 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
  133. 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
  134. 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,
  135. 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
  136. 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
  137. 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
  138. 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
  139. 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  140. 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,
  141. 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
  142. 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,
  143. 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  144. 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae,
  145. 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
  146. 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7,
  147. 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  148. 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
  149. 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
  150. 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff,
  151. 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
  152. 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,
  153. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  154. 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f
  155. };
  156. void RPC_ENTRY
  157. NdrConvert2(
  158. PMIDL_STUB_MESSAGE pStubMsg,
  159. PFORMAT_STRING pFormat,
  160. long NumberParams )
  161. /*--
  162. Routine description :
  163. This is the new stub and interpreter entry point for endian conversion.
  164. This routine handles the conversion of all parameters in a procedure.
  165. Arguments :
  166. pStubMsg - Pointer to stub message.
  167. pFormat - Format string description of procedure's parameters.
  168. NumberParams - The number of parameters in the procedure.
  169. Return :
  170. None.
  171. --*/
  172. {
  173. uchar * pBuffer;
  174. PFORMAT_STRING pFormatComplex;
  175. PFORMAT_STRING pFormatTypes;
  176. PPARAM_DESCRIPTION Params;
  177. int fClientSide;
  178. long n;
  179. //
  180. // Check if we need to do any converting.
  181. //
  182. if ( (pStubMsg->RpcMsg->DataRepresentation & (unsigned long)0X0000FFFF) ==
  183. NDR_LOCAL_DATA_REPRESENTATION )
  184. return;
  185. // Save the original buffer pointer to restore later.
  186. pBuffer = pStubMsg->Buffer;
  187. // Get the type format string.
  188. pFormatTypes = pStubMsg->StubDesc->pFormatTypes;
  189. fClientSide = pStubMsg->IsClient;
  190. Params = (PPARAM_DESCRIPTION) pFormat;
  191. for ( n = 0; n < NumberParams; n++ )
  192. {
  193. if ( fClientSide )
  194. {
  195. if ( ! Params[n].ParamAttr.IsOut )
  196. continue;
  197. }
  198. else
  199. {
  200. if ( Params[n].ParamAttr.IsPartialIgnore )
  201. {
  202. NdrSimpleTypeConvert( pStubMsg, FC_POINTER );
  203. continue;
  204. }
  205. if ( ! Params[n].ParamAttr.IsIn )
  206. continue;
  207. }
  208. if ( Params[n].ParamAttr.IsPipe )
  209. continue;
  210. if ( Params[n].ParamAttr.IsBasetype )
  211. {
  212. NdrSimpleTypeConvert( pStubMsg, Params[n].SimpleType.Type );
  213. }
  214. else
  215. {
  216. //
  217. // Complex type or pointer to complex type.
  218. //
  219. pFormatComplex = pFormatTypes + Params[n].TypeOffset;
  220. (*pfnConvertRoutines[ROUTINE_INDEX(*pFormatComplex)])
  221. ( pStubMsg,
  222. pFormatComplex,
  223. FALSE );
  224. }
  225. }
  226. pStubMsg->Buffer = pBuffer;
  227. }
  228. void RPC_ENTRY
  229. NdrConvert(
  230. PMIDL_STUB_MESSAGE pStubMsg,
  231. PFORMAT_STRING pFormat )
  232. /*--
  233. Routine description :
  234. This is the stub and interpreter entry point for endian conversion.
  235. This routine handles the conversion of all parameters in a procedure.
  236. Arguments :
  237. pStubMsg - Pointer to stub message.
  238. pFormat - Format string description of procedure's parameters.
  239. Return :
  240. None.
  241. --*/
  242. {
  243. uchar * pBuffer;
  244. PFORMAT_STRING pFormatComplex;
  245. PFORMAT_STRING pFormatTypes;
  246. int fClientSide;
  247. //
  248. // Check if we need to do any converting.
  249. //
  250. if ( (pStubMsg->RpcMsg->DataRepresentation & (unsigned long)0X0000FFFF) ==
  251. NDR_LOCAL_DATA_REPRESENTATION )
  252. return;
  253. // Save the original buffer pointer to restore later.
  254. pBuffer = pStubMsg->Buffer;
  255. // Get the type format string.
  256. pFormatTypes = pStubMsg->StubDesc->pFormatTypes;
  257. fClientSide = pStubMsg->IsClient;
  258. for ( ;; )
  259. {
  260. switch ( *pFormat )
  261. {
  262. case FC_IN_PARAM :
  263. case FC_IN_PARAM_NO_FREE_INST :
  264. if ( fClientSide )
  265. {
  266. pFormat += 4;
  267. continue;
  268. }
  269. break;
  270. case FC_IN_PARAM_BASETYPE :
  271. if ( ! fClientSide )
  272. NdrSimpleTypeConvert( pStubMsg, pFormat[1] );
  273. pFormat += 2;
  274. continue;
  275. case FC_PARTIAL_IGNORE_PARAM:
  276. if ( ! fClientSide )
  277. {
  278. NdrSimpleTypeConvert( pStubMsg, FC_LONG );
  279. pFormat += 4;
  280. continue;
  281. }
  282. // Intentional fallthrough
  283. case FC_IN_OUT_PARAM :
  284. break;
  285. case FC_OUT_PARAM :
  286. if ( ! fClientSide )
  287. {
  288. pFormat += 4;
  289. continue;
  290. }
  291. break;
  292. case FC_RETURN_PARAM :
  293. if ( ! fClientSide )
  294. {
  295. pStubMsg->Buffer = pBuffer;
  296. return;
  297. }
  298. break;
  299. case FC_RETURN_PARAM_BASETYPE :
  300. if ( fClientSide )
  301. NdrSimpleTypeConvert( pStubMsg, pFormat[1] );
  302. // We're done. Fall through.
  303. default :
  304. pStubMsg->Buffer = pBuffer;
  305. return;
  306. }
  307. //
  308. // Complex type or pointer to complex type.
  309. //
  310. pFormatComplex = pFormatTypes + *((ushort *)(pFormat + 2));
  311. (*pfnConvertRoutines[ROUTINE_INDEX(*pFormatComplex)])
  312. ( pStubMsg,
  313. pFormatComplex,
  314. FALSE );
  315. if ( *pFormat == FC_RETURN_PARAM )
  316. {
  317. pStubMsg->Buffer = pBuffer;
  318. return;
  319. }
  320. pFormat += 4;
  321. }
  322. }
  323. void
  324. NdrSimpleTypeConvert(
  325. PMIDL_STUB_MESSAGE pStubMsg,
  326. uchar FormatChar )
  327. /*--
  328. Routine description :
  329. Converts a simple type.
  330. Arguments :
  331. pStubMsg - Pointer to stub message.
  332. FormatChar - Simple type format character.
  333. Return :
  334. None.
  335. --*/
  336. {
  337. switch ( FormatChar )
  338. {
  339. case FC_CHAR :
  340. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 1 );
  341. if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_CHAR_REP_MASK) ==
  342. NDR_EBCDIC_CHAR )
  343. *(pStubMsg->Buffer) = EbcdicToAscii[*(pStubMsg->Buffer)];
  344. pStubMsg->Buffer += 1;
  345. break;
  346. case FC_BYTE :
  347. case FC_SMALL :
  348. case FC_USMALL :
  349. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 1 );
  350. pStubMsg->Buffer++;
  351. break;
  352. case FC_SHORT :
  353. case FC_USHORT :
  354. case FC_WCHAR :
  355. case FC_ENUM16 :
  356. ALIGN(pStubMsg->Buffer,1);
  357. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 2 );
  358. if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
  359. NDR_LOCAL_ENDIAN )
  360. {
  361. *((ushort *)pStubMsg->Buffer) = RtlUshortByteSwap((*(ushort *)pStubMsg->Buffer));
  362. }
  363. pStubMsg->Buffer += 2;
  364. break;
  365. case FC_LONG :
  366. case FC_ULONG :
  367. #if defined(__RPC_WIN64__)
  368. case FC_INT3264:
  369. case FC_UINT3264:
  370. #endif
  371. case FC_POINTER :
  372. case FC_ENUM32 :
  373. case FC_ERROR_STATUS_T:
  374. ALIGN(pStubMsg->Buffer,3);
  375. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 4 );
  376. if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
  377. NDR_LOCAL_ENDIAN )
  378. {
  379. *((ulong *)pStubMsg->Buffer) = RtlUlongByteSwap(*(ulong *)pStubMsg->Buffer);
  380. }
  381. pStubMsg->Buffer += 4;
  382. break;
  383. case FC_HYPER :
  384. ALIGN(pStubMsg->Buffer,7);
  385. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 8 );
  386. if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
  387. NDR_LOCAL_ENDIAN )
  388. {
  389. *((MIDL_uhyper *)pStubMsg->Buffer) = RtlUlonglongByteSwap(*(MIDL_uhyper *)pStubMsg->Buffer);
  390. }
  391. pStubMsg->Buffer += 8;
  392. break;
  393. //
  394. // VAX floating point conversions is the only one supported.
  395. //
  396. case FC_FLOAT :
  397. ALIGN(pStubMsg->Buffer,3);
  398. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 4 );
  399. if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_FLOAT_INT_MASK)
  400. != NDR_LOCAL_ENDIAN_IEEE_REP )
  401. {
  402. BOOL fEndianessDone = FALSE;
  403. if ( (pStubMsg->RpcMsg->DataRepresentation &
  404. NDR_INT_REP_MASK) != NDR_LOCAL_ENDIAN )
  405. {
  406. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  407. fEndianessDone = TRUE;
  408. }
  409. if ( (pStubMsg->RpcMsg->DataRepresentation &
  410. NDR_FLOAT_REP_MASK) != NDR_IEEE_FLOAT )
  411. {
  412. if ( fEndianessDone )
  413. pStubMsg->Buffer -= 4;
  414. if ( (pStubMsg->RpcMsg->DataRepresentation &
  415. NDR_FLOAT_REP_MASK) == NDR_VAX_FLOAT )
  416. {
  417. cvt_vax_f_to_ieee_single( pStubMsg->Buffer,
  418. 0,
  419. pStubMsg->Buffer );
  420. pStubMsg->Buffer += 4;
  421. }
  422. else if ( (pStubMsg->RpcMsg->DataRepresentation &
  423. NDR_FLOAT_REP_MASK) == NDR_IBM_FLOAT )
  424. {
  425. cvt_ibm_f_to_ieee_single( (ULONG *)pStubMsg->Buffer ) ;
  426. pStubMsg->Buffer += 4 ;
  427. }
  428. else
  429. RpcRaiseException(RPC_X_BAD_STUB_DATA);
  430. }
  431. }
  432. else
  433. pStubMsg->Buffer += 4;
  434. break;
  435. case FC_DOUBLE :
  436. ALIGN(pStubMsg->Buffer,7);
  437. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 8 );
  438. if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_FLOAT_INT_MASK)
  439. != NDR_LOCAL_ENDIAN_IEEE_REP )
  440. {
  441. BOOL fEndianessDone = FALSE;
  442. if ( (pStubMsg->RpcMsg->DataRepresentation &
  443. NDR_INT_REP_MASK) != NDR_LOCAL_ENDIAN )
  444. {
  445. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_HYPER );
  446. fEndianessDone = TRUE;
  447. }
  448. if ( (pStubMsg->RpcMsg->DataRepresentation &
  449. NDR_FLOAT_REP_MASK) != NDR_IEEE_FLOAT )
  450. {
  451. if ( fEndianessDone )
  452. pStubMsg->Buffer -= 8;
  453. if ( (pStubMsg->RpcMsg->DataRepresentation &
  454. NDR_FLOAT_REP_MASK) == NDR_VAX_FLOAT )
  455. {
  456. cvt_vax_g_to_ieee_double( pStubMsg->Buffer,
  457. 0,
  458. pStubMsg->Buffer );
  459. pStubMsg->Buffer += 8;
  460. }
  461. else if ( (pStubMsg->RpcMsg->DataRepresentation &
  462. NDR_FLOAT_REP_MASK) == NDR_IBM_FLOAT )
  463. {
  464. cvt_ibm_d_to_ieee_double( (ULONG *)pStubMsg->Buffer ) ;
  465. pStubMsg->Buffer += 8 ;
  466. }
  467. else
  468. RpcRaiseException(RPC_X_BAD_STUB_DATA);
  469. }
  470. }
  471. else
  472. pStubMsg->Buffer += 8;
  473. break;
  474. case FC_IGNORE:
  475. break;
  476. default :
  477. NDR_ASSERT(0,"NdrSimpleTypeConvert : Bad format type");
  478. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  479. return;
  480. }
  481. }
  482. void
  483. NdrpRangeConvert(
  484. PMIDL_STUB_MESSAGE pStubMsg,
  485. PFORMAT_STRING pFormat,
  486. uchar fEmbeddedPointerPass )
  487. /*--
  488. Routine description :
  489. --*/
  490. {
  491. uchar FcType = pFormat[1] & 0x0f;
  492. if ( fEmbeddedPointerPass )
  493. pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE( FcType );
  494. else
  495. NdrSimpleTypeConvert( pStubMsg, FcType );
  496. }
  497. void
  498. NdrPointerConvert(
  499. PMIDL_STUB_MESSAGE pStubMsg,
  500. PFORMAT_STRING pFormat,
  501. uchar fEmbeddedPointerPass )
  502. /*--
  503. Routine description :
  504. Converts a top level pointer and the data it points to.
  505. Pointers embedded in structures, arrays, or unions call
  506. NdrpPointerConvert directly.
  507. Used for FC_RP, FC_UP, FC_FP, FC_OP.
  508. Arguments :
  509. pStubMsg - Pointer to stub message.
  510. pFormat - Pointer's format string description.
  511. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  512. pointers in a struct/array.
  513. Return :
  514. None.
  515. --*/
  516. {
  517. uchar * pBufferMark;
  518. if ( *pFormat != FC_RP )
  519. {
  520. ALIGN(pStubMsg->Buffer,3);
  521. pBufferMark = pStubMsg->Buffer;
  522. if ( fEmbeddedPointerPass )
  523. pStubMsg->Buffer += PTR_WIRE_SIZE;
  524. else
  525. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  526. }
  527. else
  528. pBufferMark = 0;
  529. NdrpPointerConvert( pStubMsg,
  530. pBufferMark,
  531. pFormat );
  532. }
  533. void
  534. NdrpPointerConvert(
  535. PMIDL_STUB_MESSAGE pStubMsg,
  536. uchar * pBufferMark,
  537. PFORMAT_STRING pFormat )
  538. /*--
  539. Routine description :
  540. Private routine for converting a pointer and the data it points to.
  541. This is the entry point for pointers embedded in structures, arrays,
  542. and unions.
  543. Used for FC_RP, FC_UP, FC_FP, FC_OP.
  544. Arguments :
  545. pStubMsg - Pointer to stub message.
  546. pFormat - Pointer's format string description.
  547. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  548. pointers in a struct/array.
  549. Return :
  550. None.
  551. --*/
  552. {
  553. uchar uFlagsSave;
  554. switch ( *pFormat )
  555. {
  556. case FC_RP :
  557. break;
  558. case FC_UP :
  559. case FC_OP :
  560. if ( ! *((long *)pBufferMark) )
  561. return;
  562. break;
  563. case FC_FP :
  564. //
  565. // Check if we have already seen this full pointer ref id during
  566. // endian coversion. If so then we are finished with this pointer.
  567. //
  568. //
  569. if ( NdrFullPointerQueryRefId( pStubMsg->FullPtrXlatTables,
  570. *((ulong *)pBufferMark),
  571. FULL_POINTER_CONVERTED,
  572. 0 ) )
  573. return;
  574. break;
  575. default :
  576. NDR_ASSERT(0,"NdrpPointerConvert : Bad format type");
  577. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  578. return;
  579. }
  580. //
  581. // Pointer to complex type.
  582. //
  583. if ( ! SIMPLE_POINTER(pFormat[1]) )
  584. {
  585. pFormat += 2;
  586. //
  587. // Get the pointee format string.
  588. // Cast must be to a signed short since some offsets are negative.
  589. //
  590. pFormat += *((signed short *)pFormat);
  591. }
  592. else
  593. {
  594. switch ( pFormat[2] )
  595. {
  596. case FC_C_CSTRING :
  597. case FC_C_BSTRING :
  598. case FC_C_WSTRING :
  599. case FC_C_SSTRING :
  600. // Get to the string's description.
  601. pFormat += 2;
  602. break;
  603. default :
  604. // Else it's a pointer to a simple type.
  605. NdrSimpleTypeConvert( pStubMsg,
  606. pFormat[2] );
  607. return;
  608. }
  609. }
  610. //
  611. // Now lookup the proper conversion routine.
  612. //
  613. uFlagsSave = pStubMsg->uFlags;
  614. RESET_CONF_FLAGS_TO_STANDALONE(pStubMsg->uFlags);
  615. (*pfnConvertRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  616. pFormat,
  617. FALSE );
  618. pStubMsg->uFlags = uFlagsSave;
  619. }
  620. void
  621. NdrSimpleStructConvert(
  622. PMIDL_STUB_MESSAGE pStubMsg,
  623. PFORMAT_STRING pFormat,
  624. uchar fEmbeddedPointerPass )
  625. /*--
  626. Routine description :
  627. Converts a simple structure.
  628. Used for FC_STRUCT and FC_PSTRUCT.
  629. Arguments :
  630. pStubMsg - Pointer to stub message.
  631. pFormat - Structure's format string description.
  632. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  633. pointers in a struct/array.
  634. Return :
  635. None.
  636. --*/
  637. {
  638. uchar * pBufferMark;
  639. PFORMAT_STRING pFormatLayout;
  640. ALIGN(pStubMsg->Buffer,pFormat[1]);
  641. // Remember where the struct starts in the buffer.
  642. pBufferMark = pStubMsg->Buffer;
  643. pFormat += 4;
  644. if ( *pFormat == FC_PP )
  645. pFormatLayout = NdrpSkipPointerLayout( pFormat );
  646. else
  647. pFormatLayout = pFormat;
  648. //
  649. // Convert or skip the flat part of the structure.
  650. //
  651. NdrpStructConvert( pStubMsg,
  652. pFormatLayout,
  653. 0,
  654. fEmbeddedPointerPass );
  655. //
  656. // Convert the pointers. This will do nothing if
  657. // pStubMsg->IgnoreEmbeddedPointers is TRUE.
  658. //
  659. if ( *pFormat == FC_PP )
  660. {
  661. pStubMsg->BufferMark = pBufferMark;
  662. NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
  663. }
  664. }
  665. void
  666. NdrConformantStructConvert(
  667. PMIDL_STUB_MESSAGE pStubMsg,
  668. PFORMAT_STRING pFormat,
  669. uchar fEmbeddedPointerPass )
  670. /*--
  671. Routine description :
  672. Converts a conformant or conformant varying structure.
  673. Used for FC_CSTRUCT, FC_CPSTRUCT and FC_CVSTRUCT.
  674. Arguments :
  675. pStubMsg - Pointer to stub message.
  676. pFormat - Structure's format string description.
  677. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  678. pointers in a struct/array.
  679. Note that for a top level struct it can only be FALSE.
  680. Return :
  681. None.
  682. Notes.
  683. These pearls of wisdom should be recorded for posterity in the main NDR doc,
  684. but just in case, let's have them here as well.
  685. Pointer layout is generated for all structs with pointers, however it is very
  686. much different for bogus structs.
  687. A conformant struct has a pointer layout that's complete, i.e. includes pointers
  688. from conformant arrays in conformant structs. In other words, pointer layout
  689. propagates up the embedding chain of conf structs.
  690. For bogus structs, the layout has only the pointers from the current level
  691. of the bogus struct, the pointers from emebedded bogus structs are with the
  692. embedded struct and the pointers from the array are with the array.
  693. Now, arrays in conf structs don't have their own pointer layout description.
  694. However, top level arrays do have a pointer layout description as appropriate,
  695. and also conformant arrays from bogus structures do have pointer layout.
  696. So the bottom line is that a bogus struct depends on its conformant structure
  697. or on its conformant array to walk the pointers embedded therein. The only
  698. pointers described within the bogus struct are its member level pointers.
  699. Another look at it is that a conformant struct always has a full description of
  700. all the pointers contained within itself, whether in the flat portion or in the
  701. array, and so a conformant struct embedded in a bogus struct can be treated
  702. like a top level struct as far as walking its embedded pointers.
  703. (Then the outer bogus struct cannot walk its array for embedded pointers as it
  704. would if the embedded struct was another bogus struct.)
  705. So, the rule for the conformant size is simple: whoever picks up the size
  706. should also process the array for the flat part.
  707. For the embedded pointers the situation is somewhat unpleasant for the conf
  708. struct inside a bogus struct but we simplify by walking both levels.
  709. The topmost conf struct has to be walked to see the pointers and the bogus
  710. can be walked as the walk would be an empty operation.
  711. --*/
  712. {
  713. PPRIVATE_CONVERT_ROUTINE pfnConvert;
  714. uchar * pStructStart;
  715. PFORMAT_STRING pFormatArray;
  716. PFORMAT_STRING pFormatLayout;
  717. long MaxCount = 0;
  718. uchar fTopLevelStruct, fTopmostConfStruct;
  719. // We can't use pStubMsg->PointerBufferMark == 0 due to dual way ComplexStruct
  720. // routine is called. One is when embedded, another is a recursion for
  721. // embedded pointer pass.
  722. // Top level means a standalone struct, topmost means topmost conf struct,
  723. // that is topmost may be embedded in a bogus struct.
  724. fTopLevelStruct = ! IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  725. fTopmostConfStruct = ! IS_TOPMOST_CONF_STRUCT( pStubMsg->uFlags );
  726. if ( fTopLevelStruct )
  727. {
  728. ALIGN(pStubMsg->Buffer,3);
  729. // Remember the conformant size position.
  730. pStubMsg->BufferMark = pStubMsg->Buffer;
  731. //
  732. // Convert conformance count if needed.
  733. //
  734. if ( fEmbeddedPointerPass )
  735. pStubMsg->Buffer += 4;
  736. else
  737. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  738. // Get the conformance count.
  739. // This is valid because a conf struct would have only a single dim array.
  740. MaxCount = *((long *)(pStubMsg->Buffer - 4));
  741. }
  742. else
  743. {
  744. // This will be used only for the topmost case, set by bogus struct.
  745. MaxCount = *((long *)(pStubMsg->BufferMark));
  746. }
  747. ALIGN(pStubMsg->Buffer,pFormat[1]);
  748. // Remember where the struct starts in the buffer.
  749. pStructStart = pStubMsg->Buffer;
  750. pFormat += 4;
  751. // Get the array description.
  752. pFormatArray = pFormat + *((signed short *)pFormat);
  753. pFormat += 2;
  754. if ( *pFormat == FC_PP )
  755. pFormatLayout = NdrpSkipPointerLayout( pFormat );
  756. else
  757. pFormatLayout = pFormat;
  758. // When walking the struct we can descend into embedded conf structs
  759. // so mark that the top level already happened.
  760. //
  761. SET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  762. SET_TOPMOST_CONF_STRUCT(pStubMsg->uFlags);
  763. //
  764. // Convert or skip the flat part of the structure.
  765. //
  766. NdrpStructConvert( pStubMsg,
  767. pFormatLayout,
  768. 0,
  769. fEmbeddedPointerPass );
  770. // Convert the flat part of the array only if top level, as the array
  771. // description gets propagated up the embeddings.
  772. // See a note about propagating array and pointer descriptions above.
  773. if ( fTopmostConfStruct && !fEmbeddedPointerPass )
  774. {
  775. switch ( *pFormatArray )
  776. {
  777. case FC_CARRAY :
  778. pfnConvert = NdrpConformantArrayConvert;
  779. break;
  780. case FC_CVARRAY :
  781. pfnConvert = NdrpConformantVaryingArrayConvert;
  782. break;
  783. default :
  784. //
  785. // Conformant strings, but use the non-conformant string conversion
  786. // routine since we've already converted the conformant size.
  787. //
  788. NdrNonConformantStringConvert( pStubMsg,
  789. pFormatArray,
  790. fEmbeddedPointerPass );
  791. goto CheckPointers;
  792. }
  793. pStubMsg->MaxCount = MaxCount;
  794. (*pfnConvert)( pStubMsg,
  795. pFormatArray,
  796. fEmbeddedPointerPass );
  797. SET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  798. }
  799. CheckPointers:
  800. // Convert embedded pointers for the whole structure including the array
  801. RESET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  802. RESET_TOPMOST_CONF_STRUCT(pStubMsg->uFlags);
  803. // Convert pointees if the structure is standalone or if it is
  804. // topmost embedded and pointer pass
  805. if ( fTopLevelStruct // standalone && !fEmbeddedPointerPass
  806. ||
  807. fEmbeddedPointerPass && fTopmostConfStruct )
  808. {
  809. // Top level, or topmost within a bogus struct: walk the pointers.
  810. // Convert the pointers. This will do nothing if
  811. // pStubMsg->IgnoreEmbeddedPointers is TRUE.
  812. //
  813. if ( *pFormat == FC_PP )
  814. {
  815. pStubMsg->BufferMark = pStructStart;
  816. NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
  817. }
  818. SET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  819. }
  820. // Restore flags.
  821. if ( ! fTopLevelStruct)
  822. SET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  823. if ( ! fTopmostConfStruct)
  824. SET_TOPMOST_CONF_STRUCT(pStubMsg->uFlags);
  825. }
  826. #if 0
  827. void
  828. NdrHardStructConvert(
  829. PMIDL_STUB_MESSAGE pStubMsg,
  830. PFORMAT_STRING pFormat,
  831. uchar fEmbeddedPointerPass )
  832. /*--
  833. Routine description :
  834. Converts a hard structure.
  835. Used for FC_HARD_STRUCT.
  836. Arguments :
  837. pStubMsg - Pointer to stub message.
  838. pFormat - Structure's format string description.
  839. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  840. pointers in a struct/array.
  841. Return :
  842. None.
  843. Notes:
  844. pStubMsg->PointerBufferMark
  845. ! NULL indicates embedding in a complex struct.
  846. NULL indicates top level or embedding in something else
  847. So the algoritm here is
  848. if the hard struct is in a complex struct, then the complex
  849. struct is issuing two calls, first with FALSE, then with TRUE.
  850. if the hard struct is NOT in a complex struct then there is only
  851. one call and the union has to be called explicitely.
  852. --*/
  853. {
  854. uchar * BufferSaved;
  855. ALIGN(pStubMsg->Buffer,pFormat[1]);
  856. // Remember where the struct starts in the buffer.
  857. BufferSaved = pStubMsg->Buffer;
  858. //
  859. // Convert or skip the flat part of the structure.
  860. //
  861. NdrpStructConvert( pStubMsg,
  862. pFormat + 16,
  863. 0, // no pointer layout
  864. fEmbeddedPointerPass );
  865. if ( ! pStubMsg->PointerBufferMark )
  866. {
  867. //
  868. // Convert the pointers. This will do nothing if
  869. // pStubMsg->IgnoreEmbeddedPointers is TRUE.
  870. //
  871. // See if we have a union, as the pointer may be only there.
  872. //
  873. pFormat += 14;
  874. if ( *((short *)pFormat) )
  875. {
  876. //
  877. // Set the pointer to the beginning of the union:
  878. // the copy size is the struct buffer size without the union.
  879. //
  880. pStubMsg->Buffer = BufferSaved + *((short *)&pFormat[-4]);
  881. pFormat += *((short *)pFormat);
  882. (*pfnConvertRoutines[ ROUTINE_INDEX( *pFormat )])
  883. ( pStubMsg,
  884. pFormat,
  885. TRUE ); // convert the pointer only, if any.
  886. }
  887. }
  888. }
  889. #endif
  890. void
  891. NdrComplexStructConvert(
  892. PMIDL_STUB_MESSAGE pStubMsg,
  893. PFORMAT_STRING pFormat,
  894. uchar fEmbeddedPointerPass )
  895. /*--
  896. Routine description :
  897. Converts a complex structure.
  898. Used for FC_BOGUS_STRUCT.
  899. Arguments :
  900. pStubMsg - Pointer to stub message.
  901. pFormat - Structure's format string description.
  902. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  903. pointers in a struct/array.
  904. Notice a recursive call to this routine at the end.
  905. Hence, the flag can be TRUE or FALSE even for the top level
  906. bogus structures.
  907. Also, for the recursive call pStubMsg->PointerBufferMark is
  908. not 0, even for top level bogus struct.
  909. Return :
  910. None.
  911. Note about the recursive use of this routine:
  912. First pass - flat conversion pass.
  913. Convert flat part of the struct, then convert the array. For the embedded
  914. structs or arrays, go in and convert all of them without walking their
  915. pointers. The embedded conformant arrays should not be walked, only the
  916. top level one.
  917. Second pass - converting the pointees.
  918. It has to increment over the conformant size.
  919. It needs to go through the flat part of any embedded thing as for bogus
  920. the pointer members are described only at their level.
  921. It needs to go through the conf array at the top level only.
  922. --*/
  923. {
  924. uchar * pBufferSave;
  925. uchar * pBufferMark;
  926. PFORMAT_STRING pFormatSave;
  927. PFORMAT_STRING pFormatArray;
  928. PFORMAT_STRING pFormatPointers;
  929. uchar Alignment;
  930. uchar fTopLevelStruct;
  931. // We can't base the fTopLevelStruct flag upon check if
  932. // pStubMsg->PointerBufferMark == 0 due to dual way this routine is called.
  933. // One is when embedded in another struct (or array), another is a recursion
  934. // from the same level for embedded pointer pass.
  935. // Luckily, when embedded in an array, the struct can be bogus but not
  936. // conformant.
  937. fTopLevelStruct = ! IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  938. pFormatSave = pFormat;
  939. // Remember the beginning of the structure in the buffer.
  940. pBufferSave = pStubMsg->Buffer;
  941. Alignment = pFormat[1];
  942. pFormat += 4;
  943. // Get conformant array description.
  944. if ( *((ushort *)pFormat) )
  945. {
  946. long Dimensions;
  947. long i;
  948. pFormatArray = pFormat + *((signed short *)pFormat);
  949. // Skip conformant size(s) for embedded struct.
  950. if ( fTopLevelStruct )
  951. {
  952. ALIGN(pStubMsg->Buffer,3);
  953. // Mark the conformance start.
  954. pStubMsg->BufferMark = pStubMsg->Buffer;
  955. Dimensions = NdrpArrayDimensions( pStubMsg, pFormatArray, FALSE );
  956. if ( ! fEmbeddedPointerPass )
  957. {
  958. for ( i = 0; i < Dimensions; i++ )
  959. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  960. }
  961. else
  962. {
  963. pStubMsg->Buffer += Dimensions * 4;
  964. }
  965. }
  966. }
  967. else
  968. pFormatArray = 0;
  969. // Position of the conf size(s) - we will pass it to conf struct routine.
  970. pBufferMark = pStubMsg->BufferMark;
  971. pFormat += 2;
  972. // Get pointer layout description.
  973. if ( *((ushort *)pFormat) )
  974. pFormatPointers = pFormat + *((ushort *)pFormat);
  975. else
  976. pFormatPointers = 0;
  977. pFormat += 2;
  978. ALIGN(pStubMsg->Buffer,Alignment);
  979. //
  980. // Check if we are not embedded inside of another complex struct or array.
  981. //
  982. // Notice that this check depends on PointerBufferMark that gets changed.
  983. // Hence, fComplexEntry will come out FALSE for the top level struct during
  984. // the embedded pointer pass recursive call.
  985. if ( fTopLevelStruct )
  986. {
  987. //
  988. // Mark PointerBufferMark with a non-null value so complex array's
  989. // embeddings work properly.
  990. //
  991. if ( pStubMsg->PointerBufferMark == 0 )
  992. pStubMsg->PointerBufferMark = (uchar *) UlongToPtr( 0xffffffff );
  993. }
  994. //
  995. // Convert the flat part of the structure.
  996. // Or convert pointers of the flat part of the structure.
  997. //
  998. SET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  999. NdrpStructConvert( pStubMsg,
  1000. pFormat,
  1001. pFormatPointers,
  1002. fEmbeddedPointerPass );
  1003. //
  1004. // Convert any conformant array, if present.
  1005. // This converts the array flat on the first pass and the array's pointees
  1006. // during the recursive pass.
  1007. //
  1008. // Convert the array only for a top level bogus struct but not if there was
  1009. // an embedded conformant struct as this had been done already.
  1010. if ( pFormatArray && fTopLevelStruct &&
  1011. ! IS_CONF_ARRAY_DONE( pStubMsg->uFlags ) )
  1012. {
  1013. PPRIVATE_CONVERT_ROUTINE pfnConvert;
  1014. uchar fOldIgnore;
  1015. switch ( *pFormatArray )
  1016. {
  1017. case FC_CARRAY :
  1018. pfnConvert = NdrpConformantArrayConvert;
  1019. break;
  1020. case FC_CVARRAY :
  1021. pfnConvert = NdrpConformantVaryingArrayConvert;
  1022. break;
  1023. case FC_BOGUS_ARRAY :
  1024. pfnConvert = NdrpComplexArrayConvert;
  1025. break;
  1026. // case FC_C_CSTRING :
  1027. // case FC_C_BSTRING :
  1028. // case FC_C_SSTRING :
  1029. // case FC_C_WSTRING :
  1030. default :
  1031. //
  1032. // Call the non-conformant string routine since we've
  1033. // already handled the conformance count.
  1034. //
  1035. NdrNonConformantStringConvert( pStubMsg,
  1036. pFormatArray,
  1037. fEmbeddedPointerPass );
  1038. goto ComplexConvertPointers;
  1039. }
  1040. fOldIgnore = (uchar) pStubMsg->IgnoreEmbeddedPointers;
  1041. //
  1042. // Ignore embedded pointers if fEmbeddedPointerPass is false.
  1043. //
  1044. pStubMsg->IgnoreEmbeddedPointers = ! fEmbeddedPointerPass;
  1045. // Get the outermost max count for unidimensional arrays.
  1046. pStubMsg->MaxCount = *((ulong *)pBufferMark);
  1047. // Mark where conformance count(s) are.
  1048. pStubMsg->BufferMark = pBufferMark;
  1049. (*pfnConvert)( pStubMsg,
  1050. pFormatArray,
  1051. fEmbeddedPointerPass );
  1052. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1053. }
  1054. ComplexConvertPointers:
  1055. // Setup for the recursive call.
  1056. // Now start a conversion pass for embedded pointers for the complex
  1057. // struct if we're not embedded inside of another complex struct or array.
  1058. //
  1059. if ( fTopLevelStruct && ! fEmbeddedPointerPass )
  1060. {
  1061. RESET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  1062. RESET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  1063. // The first pointee.
  1064. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  1065. // Starting from the conf size again.
  1066. pStubMsg->Buffer = pBufferSave;
  1067. NdrComplexStructConvert( pStubMsg,
  1068. pFormatSave,
  1069. TRUE );
  1070. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  1071. pStubMsg->PointerBufferMark = 0;
  1072. }
  1073. // Restore the flag
  1074. if ( fTopLevelStruct )
  1075. {
  1076. RESET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  1077. RESET_CONF_ARRAY_DONE( pStubMsg->uFlags );
  1078. }
  1079. else
  1080. SET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  1081. }
  1082. void
  1083. NdrpStructConvert(
  1084. PMIDL_STUB_MESSAGE pStubMsg,
  1085. PFORMAT_STRING pFormat,
  1086. PFORMAT_STRING pFormatPointers,
  1087. uchar fEmbeddedPointerPass )
  1088. /*++
  1089. Routine description :
  1090. Converts any type of structure given a structure layout.
  1091. Does one pass converting flat part or the pointees per fEmbeddedPointerPass.
  1092. Arguments :
  1093. pStubMsg - Pointer to stub message.
  1094. pFormat - Structure layout format string description.
  1095. pFormatPointers - Pointer layout if the structure is complex,
  1096. otherwise 0.
  1097. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1098. pointers in a struct/array.
  1099. We set this to TRUE during our first pass over the structure in which
  1100. we convert the flat part of the structure and ignore embedded pointers.
  1101. This will make any embedded ok structs or ok arrays ignore their
  1102. embedded pointers until the second pass to convert embedded pointers
  1103. (at which point we'll have the correct buffer pointer to where the
  1104. pointees are).
  1105. pStubMsg->IgnoreEmbeddedPointers is preserved but does not change anything.
  1106. pStubMsg->BufferMark is preserved and passed on for the embedded conf structs.
  1107. Return :
  1108. None.
  1109. --*/
  1110. {
  1111. PFORMAT_STRING pFormatComplex;
  1112. uchar fOldIgnore;
  1113. uchar * pBufferMarkSave = pStubMsg->BufferMark;
  1114. fOldIgnore = (uchar) pStubMsg->IgnoreEmbeddedPointers;
  1115. pStubMsg->IgnoreEmbeddedPointers = ! fEmbeddedPointerPass;
  1116. //
  1117. // Convert the structure member by member.
  1118. //
  1119. for ( ; ; pFormat++ )
  1120. {
  1121. switch ( *pFormat )
  1122. {
  1123. //
  1124. // simple types
  1125. //
  1126. case FC_CHAR :
  1127. case FC_BYTE :
  1128. case FC_SMALL :
  1129. case FC_WCHAR :
  1130. case FC_SHORT :
  1131. case FC_LONG :
  1132. #if defined(__RPC_WIN64__)
  1133. case FC_INT3264 :
  1134. case FC_UINT3264 :
  1135. #endif
  1136. case FC_FLOAT :
  1137. case FC_HYPER :
  1138. case FC_DOUBLE :
  1139. case FC_ENUM16 :
  1140. case FC_ENUM32 :
  1141. if ( fEmbeddedPointerPass )
  1142. {
  1143. ALIGN(pStubMsg->Buffer,SIMPLE_TYPE_ALIGNMENT(*pFormat));
  1144. pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE(*pFormat);
  1145. }
  1146. else
  1147. {
  1148. NdrSimpleTypeConvert( pStubMsg,
  1149. *pFormat );
  1150. }
  1151. break;
  1152. case FC_IGNORE :
  1153. ALIGN(pStubMsg->Buffer,3);
  1154. pStubMsg->Buffer += PTR_WIRE_SIZE;
  1155. break;
  1156. case FC_POINTER :
  1157. //
  1158. // We can only get an FC_POINTER in a complex struct's layout.
  1159. // Pointers show up as FC_LONG in ok struct's layouts.
  1160. //
  1161. if ( fEmbeddedPointerPass )
  1162. {
  1163. uchar * pBuffer;
  1164. uchar fEmbedStruct = IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  1165. NDR_ASSERT(pFormatPointers != 0,"Internal error");
  1166. ALIGN(pStubMsg->Buffer,3);
  1167. pBuffer = pStubMsg->Buffer;
  1168. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  1169. pStubMsg->PointerBufferMark = 0;
  1170. RESET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  1171. NdrpPointerConvert( pStubMsg,
  1172. pBuffer,
  1173. pFormatPointers );
  1174. // Restore the flag
  1175. if ( fEmbedStruct )
  1176. SET_EMBED_CONF_STRUCT(pStubMsg->uFlags);
  1177. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  1178. pStubMsg->Buffer = pBuffer + PTR_WIRE_SIZE;
  1179. pFormatPointers += 4;
  1180. break;
  1181. }
  1182. else
  1183. {
  1184. NdrSimpleTypeConvert( pStubMsg,
  1185. (uchar) FC_LONG );
  1186. }
  1187. break;
  1188. //
  1189. // Embedded structures
  1190. //
  1191. case FC_EMBEDDED_COMPLEX :
  1192. pFormat += 2;
  1193. // Get the type's description.
  1194. pFormatComplex = pFormat + *((signed short UNALIGNED *)pFormat);
  1195. pStubMsg->BufferMark = pBufferMarkSave;
  1196. (*pfnConvertRoutines[ROUTINE_INDEX(*pFormatComplex)])
  1197. ( pStubMsg,
  1198. pFormatComplex,
  1199. fEmbeddedPointerPass ); // the argument as it came in
  1200. // Increment the main format string one byte. The loop
  1201. // will increment it one more byte past the offset field.
  1202. pFormat++;
  1203. break;
  1204. //
  1205. // Unused for endian conversion.
  1206. //
  1207. case FC_ALIGNM2 :
  1208. case FC_ALIGNM4 :
  1209. case FC_ALIGNM8 :
  1210. break;
  1211. case FC_STRUCTPAD1 :
  1212. case FC_STRUCTPAD2 :
  1213. case FC_STRUCTPAD3 :
  1214. case FC_STRUCTPAD4 :
  1215. case FC_STRUCTPAD5 :
  1216. case FC_STRUCTPAD6 :
  1217. case FC_STRUCTPAD7 :
  1218. break;
  1219. case FC_STRUCTPADN :
  1220. // FC_STRUCTPADN 0 <unsigned short>
  1221. pFormat += 3;
  1222. break;
  1223. case FC_PAD :
  1224. break;
  1225. //
  1226. // Done with layout.
  1227. //
  1228. case FC_END :
  1229. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1230. return;
  1231. default :
  1232. NDR_ASSERT(0,"NdrpStructConvert : Bad format type");
  1233. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1234. return;
  1235. }
  1236. }
  1237. pStubMsg->BufferMark = pBufferMarkSave;
  1238. }
  1239. void
  1240. NdrFixedArrayConvert(
  1241. PMIDL_STUB_MESSAGE pStubMsg,
  1242. PFORMAT_STRING pFormat,
  1243. uchar fEmbeddedPointerPass )
  1244. /*--
  1245. Routine description :
  1246. Converts a fixed array of any number of dimensions.
  1247. Used for FC_SMFARRAY and FC_LGFARRAY.
  1248. Arguments :
  1249. pStubMsg - Pointer to stub message.
  1250. pFormat - Array's format string description.
  1251. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1252. pointers in a struct/array.
  1253. Return :
  1254. None.
  1255. --*/
  1256. {
  1257. PFORMAT_STRING pFormatLayout;
  1258. uchar * pBufferMark;
  1259. long Elements;
  1260. uchar fOldIgnore;
  1261. ALIGN(pStubMsg->Buffer,pFormat[1]);
  1262. pBufferMark = pStubMsg->Buffer;
  1263. // Get the number of array elements.
  1264. Elements = NdrpArrayElements( pStubMsg,
  1265. 0,
  1266. pFormat );
  1267. pFormat += (*pFormat == FC_SMFARRAY) ? 4 : 6;
  1268. if ( *pFormat == FC_PP )
  1269. pFormatLayout = NdrpSkipPointerLayout( pFormat );
  1270. else
  1271. pFormatLayout = pFormat;
  1272. fOldIgnore = (uchar) pStubMsg->IgnoreEmbeddedPointers;
  1273. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  1274. NdrpArrayConvert( pStubMsg,
  1275. pFormatLayout,
  1276. Elements,
  1277. fEmbeddedPointerPass );
  1278. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1279. if ( *pFormat == FC_PP )
  1280. {
  1281. pStubMsg->BufferMark = pBufferMark;
  1282. NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
  1283. }
  1284. }
  1285. void
  1286. NdrConformantArrayConvert(
  1287. PMIDL_STUB_MESSAGE pStubMsg,
  1288. PFORMAT_STRING pFormat,
  1289. uchar fEmbeddedPointerPass )
  1290. /*--
  1291. Routine description :
  1292. Converts top level a one dimensional conformant array.
  1293. Used for FC_CARRAY.
  1294. Arguments :
  1295. pStubMsg - Pointer to stub message.
  1296. pFormat - Array's format string description.
  1297. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1298. pointers in a struct/array.
  1299. Return :
  1300. None.
  1301. --*/
  1302. {
  1303. ALIGN(pStubMsg->Buffer,3);
  1304. if ( fEmbeddedPointerPass )
  1305. pStubMsg->Buffer += 4;
  1306. else
  1307. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1308. pStubMsg->MaxCount = *((long *)(pStubMsg->Buffer - 4));
  1309. NdrpConformantArrayConvert( pStubMsg,
  1310. pFormat,
  1311. fEmbeddedPointerPass );
  1312. }
  1313. void
  1314. NdrpConformantArrayConvert(
  1315. PMIDL_STUB_MESSAGE pStubMsg,
  1316. PFORMAT_STRING pFormat,
  1317. uchar fEmbeddedPointerPass )
  1318. /*--
  1319. Routine description :
  1320. Private routine for converting a one dimensional conformant array.
  1321. This is the entry point for an embedded conformant array.
  1322. Arguments :
  1323. pStubMsg - Pointer to stub message.
  1324. pFormat - Array's format string description.
  1325. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1326. pointers in a struct/array.
  1327. Return :
  1328. None.
  1329. --*/
  1330. {
  1331. PFORMAT_STRING pFormatLayout;
  1332. uchar * pBufferMark;
  1333. long Elements;
  1334. uchar fOldIgnore;
  1335. Elements = (ulong)pStubMsg->MaxCount;
  1336. if ( ! Elements )
  1337. return;
  1338. ALIGN(pStubMsg->Buffer,pFormat[1]);
  1339. pBufferMark = pStubMsg->Buffer;
  1340. pFormat += 8;
  1341. CORRELATION_DESC_INCREMENT( pFormat );
  1342. if ( *pFormat == FC_PP )
  1343. pFormatLayout = NdrpSkipPointerLayout( pFormat );
  1344. else
  1345. pFormatLayout = pFormat;
  1346. fOldIgnore = (uchar) pStubMsg->IgnoreEmbeddedPointers;
  1347. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  1348. NdrpArrayConvert( pStubMsg,
  1349. pFormatLayout,
  1350. Elements,
  1351. fEmbeddedPointerPass );
  1352. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1353. if ( *pFormat == FC_PP )
  1354. {
  1355. pStubMsg->BufferMark = pBufferMark;
  1356. pStubMsg->MaxCount = Elements;
  1357. NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
  1358. }
  1359. }
  1360. void
  1361. NdrConformantVaryingArrayConvert(
  1362. PMIDL_STUB_MESSAGE pStubMsg,
  1363. PFORMAT_STRING pFormat,
  1364. uchar fEmbeddedPointerPass )
  1365. /*--
  1366. Routine description :
  1367. Converts a top level one dimensional conformant varying array.
  1368. Used for FC_CVARRAY.
  1369. Arguments :
  1370. pStubMsg - Pointer to stub message.
  1371. pFormat - Array's format string description.
  1372. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1373. pointers in a struct/array.
  1374. Return :
  1375. None.
  1376. --*/
  1377. {
  1378. ALIGN(pStubMsg->Buffer,3);
  1379. if ( fEmbeddedPointerPass )
  1380. pStubMsg->Buffer += 4;
  1381. else
  1382. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1383. // We don't care about the max count.
  1384. NdrpConformantVaryingArrayConvert( pStubMsg,
  1385. pFormat,
  1386. fEmbeddedPointerPass );
  1387. }
  1388. void
  1389. NdrpConformantVaryingArrayConvert(
  1390. PMIDL_STUB_MESSAGE pStubMsg,
  1391. PFORMAT_STRING pFormat,
  1392. uchar fEmbeddedPointerPass )
  1393. /*--
  1394. Routine description :
  1395. Private routine for converting a one dimensional conformant varying array.
  1396. This is the entry point for converting an embedded conformant varying
  1397. array.
  1398. Used for FC_CVARRAY.
  1399. Arguments :
  1400. pStubMsg - Pointer to stub message.
  1401. pFormat - Array's format string description.
  1402. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1403. pointers in a struct/array.
  1404. Return :
  1405. None.
  1406. --*/
  1407. {
  1408. PFORMAT_STRING pFormatLayout;
  1409. uchar * pBufferMark;
  1410. long Elements;
  1411. uchar fOldIgnore;
  1412. ALIGN(pStubMsg->Buffer,3);
  1413. // Convert offset and actual count.
  1414. if ( fEmbeddedPointerPass )
  1415. pStubMsg->Buffer += 8;
  1416. else
  1417. {
  1418. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1419. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1420. }
  1421. Elements = *((long *)(pStubMsg->Buffer - 4));
  1422. if ( ! Elements )
  1423. return;
  1424. ALIGN(pStubMsg->Buffer,pFormat[1]);
  1425. pBufferMark = pStubMsg->Buffer;
  1426. pFormat += 12;
  1427. CORRELATION_DESC_INCREMENT( pFormat );
  1428. CORRELATION_DESC_INCREMENT( pFormat );
  1429. if ( *pFormat == FC_PP )
  1430. pFormatLayout = NdrpSkipPointerLayout( pFormat );
  1431. else
  1432. pFormatLayout = pFormat;
  1433. fOldIgnore = (uchar) pStubMsg->IgnoreEmbeddedPointers;
  1434. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  1435. NdrpArrayConvert( pStubMsg,
  1436. pFormatLayout,
  1437. Elements,
  1438. fEmbeddedPointerPass );
  1439. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1440. if ( *pFormat == FC_PP )
  1441. {
  1442. pStubMsg->BufferMark = pBufferMark;
  1443. pStubMsg->MaxCount = Elements;
  1444. NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
  1445. }
  1446. }
  1447. void
  1448. NdrVaryingArrayConvert(
  1449. PMIDL_STUB_MESSAGE pStubMsg,
  1450. PFORMAT_STRING pFormat,
  1451. uchar fEmbeddedPointerPass )
  1452. /*--
  1453. Routine description :
  1454. Converts a top level or embedded varying array.
  1455. Used for FC_SMVARRAY and FC_LGVARRAY.
  1456. Arguments :
  1457. pStubMsg - Pointer to stub message.
  1458. pFormat - Array's format string description.
  1459. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1460. pointers in a struct/array.
  1461. Return :
  1462. None.
  1463. --*/
  1464. {
  1465. PFORMAT_STRING pFormatLayout;
  1466. uchar * pBufferMark;
  1467. long Elements;
  1468. uchar fOldIgnore;
  1469. ALIGN(pStubMsg->Buffer,3);
  1470. // Convert offset and actual count.
  1471. if ( fEmbeddedPointerPass )
  1472. pStubMsg->Buffer += 8;
  1473. else
  1474. {
  1475. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1476. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1477. }
  1478. Elements = *((long *)(pStubMsg->Buffer - 4));
  1479. if ( ! Elements )
  1480. return;
  1481. ALIGN(pStubMsg->Buffer,pFormat[1]);
  1482. pBufferMark = pStubMsg->Buffer;
  1483. pFormat += (*pFormat == FC_SMVARRAY) ? 12 : 16;
  1484. CORRELATION_DESC_INCREMENT( pFormat );
  1485. if ( *pFormat == FC_PP )
  1486. pFormatLayout = NdrpSkipPointerLayout( pFormat );
  1487. else
  1488. pFormatLayout = pFormat;
  1489. fOldIgnore = (uchar) pStubMsg->IgnoreEmbeddedPointers;
  1490. pStubMsg->IgnoreEmbeddedPointers = TRUE;
  1491. NdrpArrayConvert( pStubMsg,
  1492. pFormatLayout,
  1493. Elements,
  1494. fEmbeddedPointerPass );
  1495. pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
  1496. if ( *pFormat == FC_PP )
  1497. {
  1498. pStubMsg->BufferMark = pBufferMark;
  1499. pStubMsg->MaxCount = Elements;
  1500. NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
  1501. }
  1502. }
  1503. void
  1504. NdrComplexArrayConvert(
  1505. PMIDL_STUB_MESSAGE pStubMsg,
  1506. PFORMAT_STRING pFormat,
  1507. uchar fEmbeddedPointerPass )
  1508. /*--
  1509. Routine description :
  1510. Converts a top level complex array.
  1511. Used for FC_BOGUS_STRUCT.
  1512. Arguments :
  1513. pStubMsg - Pointer to stub message.
  1514. pFormat - Array's format string description.
  1515. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1516. pointers in a struct/array.
  1517. Return :
  1518. None.
  1519. --*/
  1520. {
  1521. long Dimensions;
  1522. long i;
  1523. if ( ( *((long UNALIGNED *)(pFormat + 4)) != 0xffffffff ) &&
  1524. ( pStubMsg->pArrayInfo == 0 ) )
  1525. {
  1526. ALIGN(pStubMsg->Buffer,3);
  1527. // Mark where conformance is.
  1528. pStubMsg->BufferMark = pStubMsg->Buffer;
  1529. Dimensions = NdrpArrayDimensions( pStubMsg, pFormat, FALSE );
  1530. if ( ! fEmbeddedPointerPass )
  1531. {
  1532. for ( i = 0; i < Dimensions; i++ )
  1533. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1534. }
  1535. else
  1536. pStubMsg->Buffer += Dimensions * 4;
  1537. }
  1538. NdrpComplexArrayConvert( pStubMsg,
  1539. pFormat,
  1540. fEmbeddedPointerPass );
  1541. }
  1542. void
  1543. NdrpComplexArrayConvert(
  1544. PMIDL_STUB_MESSAGE pStubMsg,
  1545. PFORMAT_STRING pFormat,
  1546. uchar fEmbeddedPointerPass )
  1547. /*--
  1548. Routine description :
  1549. Private routine for converting a complex array. This is the entry
  1550. point for converting an embedded complex array.
  1551. Used for FC_BOGUS_ARRAY.
  1552. Arguments :
  1553. pStubMsg - Pointer to stub message.
  1554. pFormat - Array's format string description.
  1555. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1556. pointers in a struct/array.
  1557. Return :
  1558. None.
  1559. --*/
  1560. {
  1561. ARRAY_INFO ArrayInfo;
  1562. PARRAY_INFO pArrayInfo;
  1563. PFORMAT_STRING pFormatSave;
  1564. uchar * pBuffer;
  1565. ULONG_PTR MaxCountSave;
  1566. long Elements;
  1567. long Dimension;
  1568. uchar Alignment;
  1569. //
  1570. // Setup if we are the outer dimension.
  1571. //
  1572. if ( ! pStubMsg->pArrayInfo )
  1573. {
  1574. pStubMsg->pArrayInfo = &ArrayInfo;
  1575. ArrayInfo.Dimension = 0;
  1576. ArrayInfo.BufferConformanceMark = (unsigned long *)pStubMsg->BufferMark;
  1577. ArrayInfo.BufferVarianceMark = 0;
  1578. }
  1579. pFormatSave = pFormat;
  1580. pArrayInfo = pStubMsg->pArrayInfo;
  1581. Dimension = pArrayInfo->Dimension;
  1582. // Remember the start of the array in the buffer.
  1583. pBuffer = pStubMsg->Buffer;
  1584. // Get the array alignment.
  1585. Alignment = pFormat[1];
  1586. pFormat += 2;
  1587. // Get number of elements (0 if conformance present).
  1588. Elements = *((ushort *&)pFormat)++;
  1589. //
  1590. // Check for conformance description.
  1591. //
  1592. if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
  1593. {
  1594. Elements = pArrayInfo->BufferConformanceMark[Dimension];
  1595. pStubMsg->MaxCount = Elements;
  1596. }
  1597. MaxCountSave = pStubMsg->MaxCount;
  1598. pFormat += 4;
  1599. CORRELATION_DESC_INCREMENT( pFormat );
  1600. //
  1601. // Check for variance description.
  1602. //
  1603. if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
  1604. {
  1605. long TotalDimensions;
  1606. long i;
  1607. if ( Dimension == 0 )
  1608. {
  1609. ALIGN(pStubMsg->Buffer,3);
  1610. pArrayInfo->BufferVarianceMark = (unsigned long *)pStubMsg->Buffer;
  1611. TotalDimensions = NdrpArrayDimensions( pStubMsg, pFormatSave, TRUE );
  1612. if ( ! fEmbeddedPointerPass )
  1613. {
  1614. //
  1615. // Convert offsets and lengths.
  1616. //
  1617. for ( i = 0; i < TotalDimensions; i++ )
  1618. {
  1619. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1620. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1621. }
  1622. }
  1623. else
  1624. pStubMsg->Buffer += TotalDimensions * 8;
  1625. }
  1626. // Overwrite Elements with the actual count.
  1627. Elements = pArrayInfo->BufferVarianceMark[(Dimension * 2) + 1];
  1628. }
  1629. pFormat += 4;
  1630. CORRELATION_DESC_INCREMENT( pFormat );
  1631. if ( Elements )
  1632. {
  1633. BOOL fComplexEntry;
  1634. uchar fIsEmbedStruct = ! IS_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  1635. ALIGN(pStubMsg->Buffer,Alignment);
  1636. //
  1637. // Check if we are not embedded inside of another complex struct or array.
  1638. //
  1639. if ( fComplexEntry = (pStubMsg->PointerBufferMark == 0) )
  1640. {
  1641. //
  1642. // Mark PointerBufferMark with a non-null value so complex array's
  1643. // or struct's which we embed will get fComplexEntry = false.
  1644. //
  1645. pStubMsg->PointerBufferMark = (uchar *) UlongToPtr( 0xffffffff );
  1646. SET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  1647. }
  1648. NdrpArrayConvert( pStubMsg,
  1649. pFormat,
  1650. Elements,
  1651. fEmbeddedPointerPass );
  1652. pArrayInfo->Dimension = Dimension;
  1653. //
  1654. // Now convert pointers in the array members.
  1655. //
  1656. if ( ! fEmbeddedPointerPass && fComplexEntry )
  1657. {
  1658. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  1659. pStubMsg->Buffer = pBuffer;
  1660. // Restore BufferMark to handle multiD arrays.
  1661. pStubMsg->BufferMark = (uchar *) ArrayInfo.BufferConformanceMark;
  1662. // Restore the original max count if we had one.
  1663. pStubMsg->MaxCount = MaxCountSave;
  1664. NdrpComplexArrayConvert( pStubMsg,
  1665. pFormatSave,
  1666. TRUE );
  1667. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  1668. pStubMsg->PointerBufferMark = 0;
  1669. }
  1670. // Restore the entry values of these flags.
  1671. if ( fComplexEntry )
  1672. {
  1673. pStubMsg->PointerBufferMark = 0;
  1674. if ( ! fIsEmbedStruct )
  1675. RESET_EMBED_CONF_STRUCT( pStubMsg->uFlags );
  1676. }
  1677. }
  1678. // pArrayInfo must be zero when not valid.
  1679. pStubMsg->pArrayInfo = (Dimension == 0) ? 0 : pArrayInfo;
  1680. }
  1681. void
  1682. NdrpArrayConvert(
  1683. PMIDL_STUB_MESSAGE pStubMsg,
  1684. PFORMAT_STRING pFormat,
  1685. long Elements,
  1686. uchar fEmbeddedPointerPass )
  1687. /*--
  1688. Routine description :
  1689. Private routine for converting any kind of array.
  1690. Arguments :
  1691. pStubMsg - Pointer to stub message.
  1692. pFormat - Array's element format string description.
  1693. Elements - Number of elements in the array.
  1694. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1695. pointers in a struct/array.
  1696. Return :
  1697. None.
  1698. --*/
  1699. {
  1700. PCONVERT_ROUTINE pfnConvert;
  1701. uchar * pBufferSave;
  1702. long Dimension;
  1703. long i;
  1704. uchar * pPointerIdMark = 0;
  1705. // Used for FC_RP only.
  1706. pBufferSave = 0;
  1707. switch ( *pFormat )
  1708. {
  1709. case FC_EMBEDDED_COMPLEX :
  1710. //
  1711. // Get the complex type description.
  1712. //
  1713. pFormat += 2;
  1714. pFormat += *((signed short UNALIGNED *)pFormat);
  1715. pfnConvert = pfnConvertRoutines[ROUTINE_INDEX(*pFormat)];
  1716. break;
  1717. case FC_RP :
  1718. case FC_IP :
  1719. // we don't want to change the behavior of these two
  1720. if (! fEmbeddedPointerPass)
  1721. return;
  1722. // fall through otherwise
  1723. case FC_UP :
  1724. case FC_FP :
  1725. case FC_OP :
  1726. pPointerIdMark = pStubMsg->Buffer;
  1727. if ( ! fEmbeddedPointerPass )
  1728. {
  1729. for ( i = 0; i < Elements; i++ )
  1730. NdrSimpleTypeConvert(pStubMsg, FC_LONG);
  1731. return;
  1732. }
  1733. if ( pStubMsg->PointerBufferMark )
  1734. {
  1735. pBufferSave = pStubMsg->Buffer;
  1736. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  1737. pStubMsg->PointerBufferMark = 0;
  1738. }
  1739. pfnConvert = (*pFormat == FC_IP) ? NdrInterfacePointerConvert:
  1740. (PCONVERT_ROUTINE) NdrpPointerConvert ;
  1741. break;
  1742. case FC_RANGE:
  1743. if ( fEmbeddedPointerPass )
  1744. {
  1745. ulong RangeSize = Elements * SIMPLE_TYPE_BUFSIZE( pFormat[1] );
  1746. CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, RangeSize );
  1747. pStubMsg->Buffer += RangeSize;
  1748. return;
  1749. }
  1750. for ( i = 0; i < Elements; i++ )
  1751. {
  1752. NdrpRangeConvert( pStubMsg, pFormat, fEmbeddedPointerPass);
  1753. }
  1754. break;
  1755. default :
  1756. //
  1757. // Simple type.
  1758. //
  1759. if ( fEmbeddedPointerPass )
  1760. {
  1761. unsigned long ArrSize = Elements * SIMPLE_TYPE_BUFSIZE(*pFormat);
  1762. CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, ArrSize );
  1763. pStubMsg->Buffer += ArrSize;
  1764. return;
  1765. }
  1766. // Optimize out an array of bytes
  1767. if ( *pFormat == FC_BYTE )
  1768. {
  1769. CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, Elements );
  1770. pStubMsg->Buffer += Elements;
  1771. return;
  1772. }
  1773. for ( i = 0; i < Elements; i++ )
  1774. {
  1775. NdrSimpleTypeConvert( pStubMsg,
  1776. *pFormat );
  1777. }
  1778. return;
  1779. }
  1780. if ( ! IS_ARRAY_OR_STRING(*pFormat) )
  1781. {
  1782. pStubMsg->pArrayInfo = 0;
  1783. }
  1784. else
  1785. {
  1786. //
  1787. // If we're dealing with a multidimensional fixed array, then pArrayInfo will
  1788. // be NULL. For non-fixed multidimensional arrays it will be valid.
  1789. //
  1790. if ( pStubMsg->pArrayInfo )
  1791. Dimension = pStubMsg->pArrayInfo->Dimension;
  1792. }
  1793. if ( pfnConvert == (PCONVERT_ROUTINE) NdrpPointerConvert )
  1794. {
  1795. ALIGN( pPointerIdMark, 3);
  1796. for ( i = 0; i < Elements; i++, pPointerIdMark += PTR_WIRE_SIZE )
  1797. {
  1798. NdrpPointerConvert( pStubMsg,
  1799. pPointerIdMark,
  1800. pFormat );
  1801. }
  1802. }
  1803. else
  1804. {
  1805. for ( i = 0; i < Elements; i++ )
  1806. {
  1807. if ( IS_ARRAY_OR_STRING(*pFormat) && pStubMsg->pArrayInfo )
  1808. pStubMsg->pArrayInfo->Dimension = Dimension + 1;
  1809. (*pfnConvert)( pStubMsg,
  1810. pFormat,
  1811. fEmbeddedPointerPass );
  1812. }
  1813. }
  1814. if ( pBufferSave )
  1815. {
  1816. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  1817. pStubMsg->Buffer = pBufferSave;
  1818. }
  1819. }
  1820. void
  1821. NdrConformantStringConvert(
  1822. PMIDL_STUB_MESSAGE pStubMsg,
  1823. PFORMAT_STRING pFormat,
  1824. uchar fEmbeddedPointerPass )
  1825. /*--
  1826. Routine description :
  1827. Converts a top level conformant string.
  1828. Used for FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and FC_C_BSTRING
  1829. (NT Beta2 compatability only).
  1830. Arguments :
  1831. pStubMsg - Pointer to stub message.
  1832. pFormat - String's format string description.
  1833. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1834. pointers in a struct/array.
  1835. Return :
  1836. None.
  1837. --*/
  1838. {
  1839. //
  1840. // If this is not part of a multidimensional array then we check if we
  1841. // have to convert the max count.
  1842. //
  1843. if ( pStubMsg->pArrayInfo == 0 )
  1844. {
  1845. ALIGN(pStubMsg->Buffer,3);
  1846. if ( fEmbeddedPointerPass )
  1847. pStubMsg->Buffer += 4;
  1848. else
  1849. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1850. }
  1851. NdrNonConformantStringConvert( pStubMsg,
  1852. pFormat,
  1853. fEmbeddedPointerPass );
  1854. }
  1855. void
  1856. NdrNonConformantStringConvert(
  1857. PMIDL_STUB_MESSAGE pStubMsg,
  1858. PFORMAT_STRING pFormat,
  1859. uchar fEmbeddedPointerPass )
  1860. /*--
  1861. Routine description :
  1862. Converts a non conformant string. This routine is also used to convert
  1863. conformant strings and is also the entry point for an embeded conformant
  1864. string.
  1865. Used for FC_CSTRING, FC_WSTRING, FC_SSTRING, FC_BSTRING (NT Beta2
  1866. compatability only), FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and
  1867. FC_C_BSTRING (NT Beta2 compatability only).
  1868. Arguments :
  1869. pStubMsg - Pointer to stub message.
  1870. pFormat - String's format string description.
  1871. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1872. pointers in a struct/array.
  1873. Return :
  1874. None.
  1875. --*/
  1876. {
  1877. uchar * pBuffer;
  1878. long Elements;
  1879. ALIGN(pStubMsg->Buffer,3);
  1880. if ( fEmbeddedPointerPass )
  1881. pStubMsg->Buffer += 8;
  1882. else
  1883. {
  1884. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1885. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  1886. }
  1887. Elements = *((long *)(pStubMsg->Buffer - 4));
  1888. pBuffer = pStubMsg->Buffer;
  1889. //
  1890. // Convert string. Remember that NdrConformantStringConvert calls this
  1891. // routine too.
  1892. //
  1893. switch ( *pFormat )
  1894. {
  1895. case FC_C_CSTRING :
  1896. case FC_C_BSTRING :
  1897. case FC_CSTRING :
  1898. case FC_BSTRING :
  1899. CHECK_ULONG_BOUND( Elements );
  1900. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + Elements );
  1901. if ( ((pStubMsg->RpcMsg->DataRepresentation & NDR_CHAR_REP_MASK) ==
  1902. NDR_EBCDIC_CHAR) && ! fEmbeddedPointerPass )
  1903. {
  1904. for ( ; Elements-- > 0; )
  1905. *pBuffer++ = EbcdicToAscii[*pBuffer];
  1906. }
  1907. else
  1908. pBuffer += Elements;
  1909. break;
  1910. case FC_C_WSTRING :
  1911. case FC_WSTRING :
  1912. CHECK_ULONG_BOUND( Elements * 2 );
  1913. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + 2 * Elements );
  1914. if ( ((pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
  1915. NDR_LOCAL_ENDIAN) && ! fEmbeddedPointerPass )
  1916. {
  1917. for ( ; Elements-- > 0; )
  1918. *((ushort *&)pBuffer)++ =
  1919. (*((ushort *)pBuffer) & MASK_A_) >> 8 |
  1920. (*((ushort *)pBuffer) & MASK__B) << 8 ;
  1921. }
  1922. else
  1923. pBuffer += Elements * 2;
  1924. break;
  1925. case FC_C_SSTRING :
  1926. case FC_SSTRING :
  1927. // Never anything to convert.
  1928. CHECK_ULONG_BOUND( Elements * pFormat[1]);
  1929. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + Elements * pFormat[1] );
  1930. pBuffer += Elements * pFormat[1];
  1931. break;
  1932. default :
  1933. NDR_ASSERT(0,"NdrNonConformantStringConvert : bad format char");
  1934. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  1935. return;
  1936. }
  1937. pStubMsg->Buffer = pBuffer;
  1938. }
  1939. void
  1940. NdrEncapsulatedUnionConvert(
  1941. PMIDL_STUB_MESSAGE pStubMsg,
  1942. PFORMAT_STRING pFormat,
  1943. uchar fEmbeddedPointerPass )
  1944. /*--
  1945. Routine description :
  1946. Converts an encapsulated union.
  1947. Used for FC_ENCAPSULATED_UNION.
  1948. Arguments :
  1949. pStubMsg - Pointer to stub message.
  1950. pFormat - Union's format string description.
  1951. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1952. pointers in a struct/array.
  1953. Return :
  1954. None.
  1955. --*/
  1956. {
  1957. uchar SwitchType;
  1958. NO_CORRELATION;
  1959. SwitchType = LOW_NIBBLE(pFormat[1]);
  1960. NdrpUnionConvert( pStubMsg,
  1961. pFormat + 4,
  1962. SwitchType,
  1963. fEmbeddedPointerPass );
  1964. }
  1965. void
  1966. NdrNonEncapsulatedUnionConvert(
  1967. PMIDL_STUB_MESSAGE pStubMsg,
  1968. PFORMAT_STRING pFormat,
  1969. uchar fEmbeddedPointerPass )
  1970. /*--
  1971. Routine description :
  1972. Converts an non-encapsulated union.
  1973. Used for FC_NON_ENCAPSULATED_UNION.
  1974. Arguments :
  1975. pStubMsg - Pointer to stub message.
  1976. pFormat - Union's format string description.
  1977. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  1978. pointers in a struct/array.
  1979. Return :
  1980. None.
  1981. --*/
  1982. {
  1983. uchar SwitchType;
  1984. SwitchType = pFormat[1];
  1985. pFormat += 6;
  1986. CORRELATION_DESC_INCREMENT( pFormat );
  1987. pFormat += *((signed short *)pFormat);
  1988. pFormat += 2;
  1989. NdrpUnionConvert( pStubMsg,
  1990. pFormat,
  1991. SwitchType,
  1992. fEmbeddedPointerPass );
  1993. }
  1994. void
  1995. NdrpUnionConvert(
  1996. PMIDL_STUB_MESSAGE pStubMsg,
  1997. PFORMAT_STRING pFormat,
  1998. uchar SwitchType,
  1999. uchar fEmbeddedPointerPass )
  2000. /*--
  2001. Routine description :
  2002. Private routine for converting a union shared by encapsulated and
  2003. non-encapsulated unions.
  2004. Arguments :
  2005. pStubMsg - Pointer to stub message.
  2006. pFormat - Union's format string description.
  2007. SwitchType - Union's format char switch type.
  2008. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  2009. pointers in a struct/array.
  2010. Return :
  2011. None.
  2012. --*/
  2013. {
  2014. long SwitchIs;
  2015. long Arms;
  2016. uchar Alignment;
  2017. //
  2018. // Convert the switch_is().
  2019. //
  2020. if ( fEmbeddedPointerPass )
  2021. {
  2022. ALIGN(pStubMsg->Buffer,SIMPLE_TYPE_ALIGNMENT(SwitchType));
  2023. pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE(SwitchType);
  2024. }
  2025. else
  2026. {
  2027. NdrSimpleTypeConvert( pStubMsg,
  2028. SwitchType );
  2029. }
  2030. switch ( SwitchType )
  2031. {
  2032. case FC_SMALL :
  2033. case FC_CHAR :
  2034. SwitchIs = (long) *((char *)(pStubMsg->Buffer - 1));
  2035. break;
  2036. case FC_USMALL :
  2037. SwitchIs = (long) *((uchar *)(pStubMsg->Buffer - 1));
  2038. break;
  2039. case FC_SHORT :
  2040. case FC_ENUM16 :
  2041. SwitchIs = (long) *((short *)(pStubMsg->Buffer - 2));
  2042. break;
  2043. case FC_USHORT :
  2044. case FC_WCHAR :
  2045. SwitchIs = (long) *((ushort *)(pStubMsg->Buffer - 2));
  2046. break;
  2047. case FC_LONG :
  2048. case FC_ULONG :
  2049. case FC_ENUM32 :
  2050. // FC_INT3264 gets mapped to FC_LONG.
  2051. SwitchIs = *((long *)(pStubMsg->Buffer - 4));
  2052. break;
  2053. default :
  2054. NDR_ASSERT(0,"NdrpUnionConvert : bad switch value");
  2055. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  2056. return;
  2057. }
  2058. //
  2059. // We're at the union_arms<2> field now, which contains both the
  2060. // Microsoft union aligment value and the number of union arms.
  2061. //
  2062. //
  2063. // Get the union alignment (0 if this is a DCE union).
  2064. //
  2065. Alignment = (uchar) ( *((ushort *)pFormat) >> 12 );
  2066. ALIGN(pStubMsg->Buffer,Alignment);
  2067. //
  2068. // Number of arms is the lower 12 bits.
  2069. //
  2070. Arms = (long) ( *((ushort *&)pFormat)++ & 0x0fff);
  2071. for ( ; Arms; Arms-- )
  2072. {
  2073. if ( *((long UNALIGNED *&)pFormat)++ == SwitchIs )
  2074. {
  2075. //
  2076. // Found the right arm, break out.
  2077. //
  2078. break;
  2079. }
  2080. // Else increment format string.
  2081. pFormat += 2;
  2082. }
  2083. //
  2084. // Check if we took the default arm and no default arm is specified.
  2085. //
  2086. if ( ! Arms && (*((ushort *)pFormat) == (ushort) 0xffff) )
  2087. {
  2088. RpcRaiseException( RPC_S_INVALID_TAG );
  2089. }
  2090. //
  2091. // Return if the arm has no description.
  2092. //
  2093. if ( ! *((ushort *)pFormat) )
  2094. return;
  2095. //
  2096. // Get the arm's description.
  2097. //
  2098. // We need a real solution after beta for simple type arms. This could
  2099. // break if we have a format string larger than about 32K.
  2100. //
  2101. if ( IS_MAGIC_UNION_BYTE(pFormat) )
  2102. {
  2103. // Convert an arm of a simple type
  2104. if ( fEmbeddedPointerPass )
  2105. {
  2106. ALIGN( pStubMsg->Buffer, SIMPLE_TYPE_ALIGNMENT( pFormat[0] ));
  2107. pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE( pFormat[0] );
  2108. }
  2109. else
  2110. NdrSimpleTypeConvert( pStubMsg, pFormat[0] );
  2111. return;
  2112. }
  2113. pFormat += *((signed short *)pFormat);
  2114. //
  2115. // We have to do special things for a union arm which is a pointer when
  2116. // we have a union embedded in a complex struct or array.
  2117. //
  2118. if ( IS_BASIC_POINTER(*pFormat) && pStubMsg->PointerBufferMark )
  2119. {
  2120. uchar * pBufferMark;
  2121. //
  2122. // If we're not in the embedded pointer pass then just convert the
  2123. // pointer value.
  2124. //
  2125. if ( ! fEmbeddedPointerPass )
  2126. {
  2127. NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
  2128. return;
  2129. }
  2130. pBufferMark = pStubMsg->Buffer;
  2131. // Align pBufferMark.
  2132. ALIGN(pBufferMark,3);
  2133. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  2134. pStubMsg->PointerBufferMark = 0;
  2135. //
  2136. // We must call the private pointer conversion routine.
  2137. //
  2138. NdrpPointerConvert( pStubMsg,
  2139. pBufferMark,
  2140. pFormat );
  2141. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  2142. pStubMsg->Buffer = pBufferMark + PTR_WIRE_SIZE;
  2143. return;
  2144. }
  2145. //
  2146. // Union arm of a complex type.
  2147. //
  2148. (*pfnConvertRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  2149. pFormat,
  2150. fEmbeddedPointerPass );
  2151. }
  2152. void
  2153. NdrByteCountPointerConvert(
  2154. PMIDL_STUB_MESSAGE pStubMsg,
  2155. PFORMAT_STRING pFormat,
  2156. uchar fEmbeddedPointerPass )
  2157. /*--
  2158. Routine description :
  2159. Converts a byte count pointer.
  2160. Used for FC_BYTE_COUNT_POINTER.
  2161. Arguments :
  2162. pStubMsg - Pointer to stub message.
  2163. pFormat - Byte count pointer format string description.
  2164. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  2165. pointers in a struct/array.
  2166. Return :
  2167. None.
  2168. --*/
  2169. {
  2170. if ( pFormat[1] != FC_PAD )
  2171. {
  2172. NdrSimpleTypeConvert( pStubMsg, pFormat[1] );
  2173. return;
  2174. }
  2175. pFormat += 6;
  2176. CORRELATION_DESC_INCREMENT( pFormat );
  2177. pFormat += *((short *)pFormat);
  2178. (*pfnConvertRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
  2179. pFormat,
  2180. fEmbeddedPointerPass );
  2181. }
  2182. void
  2183. NdrXmitOrRepAsConvert(
  2184. PMIDL_STUB_MESSAGE pStubMsg,
  2185. PFORMAT_STRING pFormat,
  2186. uchar fEmbeddedPointerPass )
  2187. /*--
  2188. Routine description :
  2189. Converts a transmit as or represent as transmited object.
  2190. Arguments :
  2191. pStubMsg - Pointer to stub message.
  2192. pFormat - s format string description.
  2193. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  2194. pointers in a struct/array.
  2195. Return :
  2196. None.
  2197. --*/
  2198. {
  2199. PFORMAT_STRING pTransFormat;
  2200. // Transmitted type cannot have pointers in it, as of now,
  2201. // so if this is a embedded pointer pass, just return.
  2202. if ( fEmbeddedPointerPass )
  2203. return;
  2204. // Go to the transmitted type and convert it.
  2205. pFormat += 8;
  2206. pTransFormat = pFormat + *(short *)pFormat;
  2207. if ( IS_SIMPLE_TYPE( *pTransFormat ) )
  2208. {
  2209. NdrSimpleTypeConvert( pStubMsg, *pTransFormat );
  2210. }
  2211. else
  2212. {
  2213. (*pfnConvertRoutines[ ROUTINE_INDEX( *pTransFormat) ])
  2214. ( pStubMsg,
  2215. pTransFormat,
  2216. fEmbeddedPointerPass );
  2217. }
  2218. }
  2219. void
  2220. NdrUserMarshalConvert(
  2221. PMIDL_STUB_MESSAGE pStubMsg,
  2222. PFORMAT_STRING pFormat,
  2223. uchar fEmbeddedPointerPass )
  2224. /*--
  2225. Routine description :
  2226. Converts a user_marshal object using the transmissible type description.
  2227. Arguments :
  2228. pStubMsg - Pointer to stub message.
  2229. pFormat - not used
  2230. fEmbeddedPointerPass - not used
  2231. Return :
  2232. None.
  2233. --*/
  2234. {
  2235. PFORMAT_STRING pTransFormat;
  2236. // Go to the transmissible type and convert it.
  2237. pFormat += 8;
  2238. pTransFormat = pFormat + *(short *)pFormat;
  2239. if ( IS_SIMPLE_TYPE( *pTransFormat ) )
  2240. {
  2241. if ( fEmbeddedPointerPass )
  2242. return;
  2243. NdrSimpleTypeConvert( pStubMsg, *pTransFormat );
  2244. }
  2245. else
  2246. {
  2247. // It may have pointers in it.
  2248. if ( IS_POINTER_TYPE(*pTransFormat) && pStubMsg->PointerBufferMark )
  2249. {
  2250. // Embedded case and the type is a pointer type.
  2251. if ( fEmbeddedPointerPass )
  2252. {
  2253. uchar * BufferSave = pStubMsg->Buffer;
  2254. // Get the pointee type and convert it.
  2255. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  2256. pTransFormat += 2;
  2257. pTransFormat += *(short *)pTransFormat;
  2258. if ( IS_SIMPLE_TYPE( *pTransFormat ) )
  2259. {
  2260. NdrSimpleTypeConvert( pStubMsg, *pTransFormat );
  2261. }
  2262. else
  2263. {
  2264. uchar uFlagsSave;
  2265. uFlagsSave = pStubMsg->uFlags;
  2266. RESET_CONF_FLAGS_TO_STANDALONE(pStubMsg->uFlags);
  2267. // Convert the pointee as if not embedded.
  2268. pStubMsg->PointerBufferMark = 0;
  2269. (*pfnConvertRoutines[ ROUTINE_INDEX( *pTransFormat) ])
  2270. ( pStubMsg,
  2271. pTransFormat,
  2272. FALSE );
  2273. pStubMsg->uFlags = uFlagsSave;
  2274. // Set the pointee marker behind the converted whole.
  2275. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  2276. }
  2277. // Now step over the original pointer.
  2278. pStubMsg->Buffer = BufferSave;
  2279. ALIGN(pStubMsg->Buffer,3);
  2280. pStubMsg->Buffer += PTR_WIRE_SIZE;
  2281. }
  2282. else
  2283. {
  2284. // Convert the pointer itself only.
  2285. // We can't call ptr convert routine because of the pointee.
  2286. NdrSimpleTypeConvert( pStubMsg, FC_LONG );
  2287. }
  2288. }
  2289. else
  2290. {
  2291. // Non embedded pointer type or
  2292. // (embedded or not) a non-pointer or a non-simple type.
  2293. // Just call the appropriate conversion routine.
  2294. (*pfnConvertRoutines[ ROUTINE_INDEX( *pTransFormat) ])
  2295. ( pStubMsg,
  2296. pTransFormat,
  2297. fEmbeddedPointerPass );
  2298. }
  2299. }
  2300. }
  2301. unsigned char * RPC_ENTRY
  2302. NdrUserMarshalSimpleTypeConvert(
  2303. unsigned long * pFlags,
  2304. unsigned char * pBuffer,
  2305. unsigned char FormatChar )
  2306. /*--
  2307. Routine description :
  2308. Converts a simple type supplied from a user_marshal unmarshaled routine.
  2309. Note that this is *not* supposed to be called when the NDR engine walks
  2310. the wire type description to convert.
  2311. Arguments :
  2312. pFlags - flags as for user_marshal routines: data rep, context.
  2313. pBuffer - current buffer pointer supplied by the user
  2314. FormatChar - specifies the type
  2315. Return :
  2316. None.
  2317. --*/
  2318. {
  2319. uchar * pBufferSave;
  2320. USER_MARSHAL_CB * pUserCB = (USER_MARSHAL_CB *)pFlags;
  2321. MIDL_STUB_MESSAGE * pStubMsg = pUserCB->pStubMsg;
  2322. if ( pBuffer < pStubMsg->BufferStart ||
  2323. pBuffer > pStubMsg->BufferEnd ||
  2324. ( (*pFlags >> 16) !=
  2325. (pStubMsg->RpcMsg->DataRepresentation & (ulong)0x0000FFFF) )
  2326. )
  2327. RpcRaiseException( RPC_S_INVALID_ARG );
  2328. pBufferSave = pStubMsg->Buffer;
  2329. pStubMsg->Buffer = pBuffer;
  2330. NdrSimpleTypeConvert( pStubMsg, FormatChar );
  2331. pBuffer = pStubMsg->Buffer;
  2332. pStubMsg->Buffer = pBufferSave;
  2333. return ( pBuffer );
  2334. }
  2335. void
  2336. NdrInterfacePointerConvert(
  2337. PMIDL_STUB_MESSAGE pStubMsg,
  2338. PFORMAT_STRING pFormat,
  2339. uchar fEmbeddedPointerPass )
  2340. /*--
  2341. Routine description :
  2342. Converts an interface pointer.
  2343. Arguments :
  2344. pStubMsg - Pointer to stub message.
  2345. pFormat - Xmit/Rep as format string description.
  2346. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  2347. pointers in a struct/array.
  2348. Return :
  2349. None.
  2350. --*/
  2351. {
  2352. uchar * pBufferSave;
  2353. unsigned long *pLength;
  2354. // Align for getting the pointer's node id.
  2355. ALIGN( pStubMsg->Buffer, 0x3 );
  2356. //
  2357. // If we're ignoring embedded pointers then we simply convert the pointer's
  2358. // node id and return. Otherwise, we skip the pointer's node id and
  2359. // continue on to convert the actuall interface pointer.
  2360. //
  2361. if ( ! fEmbeddedPointerPass )
  2362. {
  2363. NdrSimpleTypeConvert( pStubMsg, FC_LONG );
  2364. if ( pStubMsg->PointerBufferMark != 0 )
  2365. return;
  2366. pStubMsg->Buffer -= PTR_WIRE_SIZE;
  2367. }
  2368. // Skip the pointer's node id, which will already have been converted.
  2369. //
  2370. // Also, we don't have the pointee if the pointer itself is null;
  2371. // An interface pointer behaves like a unique pointer.
  2372. if ( *((long *&)pStubMsg->Buffer)++ == 0 )
  2373. return;
  2374. //
  2375. // Check if we're handling pointers in a complex struct, and re-set the
  2376. // Buffer pointer if so.
  2377. //
  2378. if ( pStubMsg->PointerBufferMark )
  2379. {
  2380. pBufferSave = pStubMsg->Buffer;
  2381. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  2382. pStubMsg->PointerBufferMark = 0;
  2383. }
  2384. else
  2385. pBufferSave = 0;
  2386. //
  2387. // Convert the conformant size and the count field.
  2388. //
  2389. NdrSimpleTypeConvert( pStubMsg, FC_LONG );
  2390. pLength = (unsigned long *) pStubMsg->Buffer;
  2391. NdrSimpleTypeConvert( pStubMsg, FC_LONG );
  2392. // Skip over the marshalled interface pointer.
  2393. CHECK_EOB_RAISE_IB( pStubMsg->Buffer + *pLength );
  2394. pStubMsg->Buffer += *pLength;
  2395. //
  2396. // Re-set the buffer pointer if needed.
  2397. //
  2398. if ( pBufferSave )
  2399. {
  2400. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  2401. pStubMsg->Buffer = pBufferSave;
  2402. }
  2403. }
  2404. void
  2405. NdrContextHandleConvert(
  2406. PMIDL_STUB_MESSAGE pStubMsg,
  2407. PFORMAT_STRING pFormat,
  2408. uchar fEmbeddedPointerPass )
  2409. /*--
  2410. Routine description :
  2411. Conversion routine for context handles, only increments the buffer.
  2412. Arguments :
  2413. pStubMsg - Pointer to stub message.
  2414. pFormat - Format string description.
  2415. fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
  2416. pointers in a struct/array.
  2417. Return :
  2418. None.
  2419. --*/
  2420. {
  2421. ALIGN(pStubMsg->Buffer,0x3);
  2422. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + CONTEXT_HANDLE_WIRE_SIZE );
  2423. pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE;
  2424. }
  2425. void
  2426. NdrpEmbeddedPointerConvert(
  2427. PMIDL_STUB_MESSAGE pStubMsg,
  2428. PFORMAT_STRING pFormat )
  2429. /*--
  2430. Routine description :
  2431. Private routine for converting an array's or a structure's embedded
  2432. pointers.
  2433. Arguments :
  2434. pStubMsg - Pointer to stub message.
  2435. pFormat - Pointer layout format string description.
  2436. Return :
  2437. None.
  2438. --*/
  2439. {
  2440. uchar * pBufferMark;
  2441. uchar * pBufferPointer;
  2442. uchar * pBufferSave;
  2443. ULONG_PTR MaxCountSave;
  2444. MaxCountSave = pStubMsg->MaxCount;
  2445. //
  2446. // Return if we're ignoring embedded pointers.
  2447. //
  2448. if ( pStubMsg->IgnoreEmbeddedPointers )
  2449. return;
  2450. //
  2451. // Check if we're handling pointers in a complex struct, and re-set the
  2452. // Buffer pointer if so.
  2453. //
  2454. if ( pStubMsg->PointerBufferMark )
  2455. {
  2456. pBufferSave = pStubMsg->Buffer;
  2457. pStubMsg->Buffer = pStubMsg->PointerBufferMark;
  2458. pStubMsg->PointerBufferMark = 0;
  2459. }
  2460. else
  2461. pBufferSave = 0;
  2462. pBufferMark = pStubMsg->BufferMark;
  2463. //
  2464. // Increment past the FC_PP and pad.
  2465. //
  2466. pFormat += 2;
  2467. for (;;)
  2468. {
  2469. if ( *pFormat == FC_END )
  2470. {
  2471. if ( pBufferSave )
  2472. {
  2473. pStubMsg->PointerBufferMark = pStubMsg->Buffer;
  2474. pStubMsg->Buffer = pBufferSave;
  2475. }
  2476. return;
  2477. }
  2478. // Check for a repeat pointer.
  2479. if ( *pFormat != FC_NO_REPEAT )
  2480. {
  2481. pStubMsg->MaxCount = MaxCountSave;
  2482. pFormat = NdrpEmbeddedRepeatPointerConvert( pStubMsg, pFormat );
  2483. // Continue to the next pointer.
  2484. continue;
  2485. }
  2486. // Increment to the buffer pointer offset.
  2487. pFormat += 4;
  2488. pBufferPointer = pBufferMark + *((signed short *&)pFormat)++;
  2489. NdrpPointerConvert( pStubMsg,
  2490. pBufferPointer,
  2491. pFormat );
  2492. // Increment past the pointer description.
  2493. pFormat += 4;
  2494. }
  2495. }
  2496. PFORMAT_STRING
  2497. NdrpEmbeddedRepeatPointerConvert(
  2498. PMIDL_STUB_MESSAGE pStubMsg,
  2499. PFORMAT_STRING pFormat )
  2500. /*--
  2501. Routine description :
  2502. Private routine for converting an array's embedded pointers.
  2503. Arguments :
  2504. pStubMsg - Pointer to stub message.
  2505. pFormat - Pointer layout format string description.
  2506. Return :
  2507. Format string pointer past the array's pointer layout description.
  2508. --*/
  2509. {
  2510. uchar * pBufPtr;
  2511. uchar * pBufferMark;
  2512. PFORMAT_STRING pFormatSave;
  2513. ulong RepeatCount,RepeatIncrement, Pointers, PointersSave;
  2514. pBufferMark = pStubMsg->BufferMark;
  2515. // Get the repeat count.
  2516. switch ( *pFormat )
  2517. {
  2518. case FC_FIXED_REPEAT :
  2519. pFormat += 2;
  2520. RepeatCount = *((ushort *)pFormat);
  2521. break;
  2522. case FC_VARIABLE_REPEAT :
  2523. RepeatCount = (ulong)pStubMsg->MaxCount;
  2524. break;
  2525. default :
  2526. NDR_ASSERT(0,"NdrpEmbeddedRepeatPointerConvert : bad format");
  2527. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  2528. return 0;
  2529. }
  2530. pFormat += 2;
  2531. RepeatIncrement = *((ushort *&)pFormat)++;
  2532. // array_offset is ignored
  2533. pFormat += 2;
  2534. // Get number of pointers.
  2535. Pointers = *((ushort *&)pFormat)++;
  2536. pFormatSave = pFormat;
  2537. PointersSave = Pointers;
  2538. for ( ; RepeatCount--;
  2539. pBufferMark += RepeatIncrement )
  2540. {
  2541. pFormat = pFormatSave;
  2542. Pointers = PointersSave;
  2543. for ( ; Pointers--; )
  2544. {
  2545. pFormat += 2;
  2546. pBufPtr = pBufferMark + *((signed short *&)pFormat)++;
  2547. NdrpPointerConvert( pStubMsg,
  2548. pBufPtr,
  2549. pFormat );
  2550. // Increment past the pointer description.
  2551. pFormat += 4;
  2552. }
  2553. }
  2554. return pFormatSave + PointersSave * 8;
  2555. }