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.

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