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.

1179 lines
34 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dataconv.cxx
  5. Abstract:
  6. This file contains routines used by the RPC stubs to assist in marshalling
  7. and unmarshalling data to and from an RPC message buffer. Each routine
  8. receives as a parameter a format string which drives its actions. The
  9. valid characters for the format string are :
  10. c - charater
  11. b - byte
  12. w - wide charater or short
  13. l - long
  14. f - float
  15. d - double
  16. s1, s2, sb - string of chars, wide chars, or bytes
  17. z - byte string
  18. )2, )4, )8,
  19. (2, (4, (8,
  20. 1, 2, 4, 8 - various alignment directives
  21. For more details consult the Network Computing Architecture documentation
  22. on Network Data Representation.
  23. Author:
  24. Donna Liu (donnali) 09-Nov-1990
  25. Revision History:
  26. 26-Feb-1992 donnali
  27. Moved toward NT coding style.
  28. 09-Jul-1993 DKays
  29. Made wholesale source level optimizations for speed and size.
  30. --*/
  31. #include <sysinc.h>
  32. #include <rpc.h>
  33. #include <rpcndr.h>
  34. #include <ndrlibp.h>
  35. //
  36. // alignment macros
  37. //
  38. #define ALIGN(buffer,increment) \
  39. (((ULONG_PTR)buffer + increment) & ~ increment)
  40. #define ALIGN2(buffer) \
  41. (((ULONG_PTR)buffer + 1) & ~1)
  42. #define ALIGN4(buffer) \
  43. (((ULONG_PTR)buffer + 3) & ~3)
  44. #define ALIGN8(buffer) \
  45. (((ULONG_PTR)buffer + 7) & ~7)
  46. // local routines
  47. static unsigned long NdrStrlenStrcpy ( char *, char * );
  48. static unsigned long NdrWStrlenStrcpy ( wchar_t *, wchar_t * );
  49. void RPC_ENTRY
  50. data_from_ndr (
  51. PRPC_MESSAGE source,
  52. void * target,
  53. char * format,
  54. unsigned char MscPak)
  55. /*++
  56. Routine Description:
  57. This routine copies data from the runtime buffer.
  58. Arguments:
  59. source - RPC message structure passed from the runtime to the stub.
  60. target - Buffer to receive the unmarshalled data.
  61. format - Format of the data.
  62. MscPak - Packing level.
  63. --*/
  64. {
  65. unsigned long valid_lower;
  66. unsigned long valid_total;
  67. register char *pSource;
  68. register char *pTarget;
  69. unsigned long pack2, pack4, pack8;
  70. unsigned long pack, align;
  71. // pre-compute the possible alignment masks
  72. if ( MscPak )
  73. MscPak--;
  74. pack2 = MscPak & 0x1;
  75. pack4 = MscPak & 0x3;
  76. pack8 = MscPak & 0x7;
  77. pSource = (char *) source->Buffer;
  78. if ((source->DataRepresentation & (unsigned long)0X0000FFFF) ==
  79. NDR_LOCAL_DATA_REPRESENTATION)
  80. {
  81. pTarget = (char *) target;
  82. for (;;)
  83. {
  84. switch ( *format++ )
  85. {
  86. case 'b' :
  87. case 'c' :
  88. *((char *)pTarget) = *((char *)pSource);
  89. pTarget += 1;
  90. pSource += 1;
  91. break;
  92. case 'w' :
  93. pSource = (char *) ALIGN2(pSource);
  94. pTarget = (char *) ALIGN(pTarget,pack2);
  95. *((short *)pTarget) = *((short *)pSource);
  96. pTarget += 2;
  97. pSource += 2;
  98. break;
  99. case 'l' :
  100. case 'f' :
  101. pSource = (char *) ALIGN4(pSource);
  102. pTarget = (char *) ALIGN(pTarget,pack4);
  103. *((long *)pTarget) = *((long *)pSource);
  104. pTarget += 4;
  105. pSource += 4;
  106. break;
  107. case 'h' :
  108. case 'd' :
  109. pSource = (char *) ALIGN8(pSource);
  110. pTarget = (char *) ALIGN(pTarget,pack8);
  111. #if defined(DOS) || defined(WIN)
  112. *((DWORD *) pTarget) = *((DWORD *) &pSource);
  113. *(((DWORD *) pTarget) + 1) = *(((DWORD *) &pSource) + 1);
  114. #else
  115. *((__int64 *)pTarget) = *((__int64 *)pSource);
  116. #endif
  117. pTarget += 8;
  118. pSource += 8;
  119. break;
  120. case 's' :
  121. pSource = (char *) ALIGN4(pSource);
  122. valid_lower = *((long *)pSource);
  123. pSource += 4;
  124. valid_total = *((long *)pSource);
  125. pSource += 4;
  126. // double the valid_total if this is a wide char string
  127. if ( *format++ == '2' )
  128. valid_total <<= 1;
  129. RpcpMemoryCopy(pTarget,
  130. pSource,
  131. valid_total);
  132. pTarget += valid_total;
  133. pSource += valid_total;
  134. break;
  135. case 'z' :
  136. pSource = (char *) ALIGN4(pSource);
  137. valid_total = *((long *)pSource);
  138. pSource += 4;
  139. *((int *)pTarget - 1) = (int) valid_total;
  140. // double the valid_total if this is a wide char string
  141. if ( *format++ == '2' )
  142. valid_total <<= 1;
  143. RpcpMemoryCopy(pTarget,
  144. pSource,
  145. valid_total);
  146. pTarget += valid_total;
  147. pSource += valid_total;
  148. break;
  149. case 'p' :
  150. pSource = (char *) ALIGN4(pSource);
  151. pTarget = (char *) ALIGN(pTarget,pack4);
  152. pTarget += 4;
  153. pSource += 4;
  154. break;
  155. case '(' :
  156. // *format == '2', '4', or '8'; align = 1, 3, or 7
  157. align = *format - '0' - 1;
  158. pSource = (char *) ALIGN(pSource,align);
  159. case ')' :
  160. switch ( *format++ )
  161. {
  162. case '8' :
  163. pack = pack8;
  164. break;
  165. case '4' :
  166. pack = pack4;
  167. break;
  168. case '2' :
  169. pack = pack2;
  170. break;
  171. default :
  172. continue;
  173. }
  174. pTarget = (char *) ALIGN(pTarget,pack);
  175. break;
  176. case '8' :
  177. pSource = (char *) ALIGN8(pSource);
  178. break;
  179. case '4' :
  180. pSource = (char *) ALIGN4(pSource);
  181. break;
  182. case '2' :
  183. pSource = (char *) ALIGN2(pSource);
  184. break;
  185. case '1' :
  186. break;
  187. default :
  188. source->Buffer = pSource;
  189. return;
  190. } // switch
  191. } // for
  192. } // if
  193. else
  194. {
  195. for (;;)
  196. {
  197. switch ( *format++ )
  198. {
  199. case 'b' :
  200. *((char *)target) = *((char *)source->Buffer);
  201. source->Buffer = (void *)((ULONG_PTR)source->Buffer + 1);
  202. target = (void *)((ULONG_PTR)target + 1);
  203. break;
  204. case 'c' :
  205. char_from_ndr(source,(unsigned char *)target);
  206. target = (void *)((ULONG_PTR)target + 1);
  207. break;
  208. case 'w' :
  209. target = (void *) ALIGN(target,pack2);
  210. short_from_ndr(source,(unsigned short *)target);
  211. target = (void *)((ULONG_PTR)target + 2);
  212. break;
  213. case 'l' :
  214. target = (void *) ALIGN(target,pack4);
  215. long_from_ndr(source,(unsigned long *)target);
  216. target = (void *)((ULONG_PTR)target + 4);
  217. break;
  218. case 'f' :
  219. target = (void *) ALIGN(target,pack4);
  220. float_from_ndr(source, target);
  221. target = (void *)((ULONG_PTR)target + 4);
  222. break;
  223. case 'd' :
  224. target = (void *) ALIGN(target,pack8);
  225. double_from_ndr(source, target);
  226. target = (void *)((ULONG_PTR)target + 8);
  227. break;
  228. case 'h' :
  229. target = (void *) ALIGN(target,pack8);
  230. hyper_from_ndr(source, (hyper *)target);
  231. target = (void *)((ULONG_PTR)target + 8);
  232. break;
  233. case 's' :
  234. long_from_ndr(source, &valid_lower);
  235. long_from_ndr(source, &valid_total);
  236. switch ( *format++ )
  237. {
  238. case '2' :
  239. short_array_from_ndr (source,
  240. 0,
  241. valid_total,
  242. (unsigned short *)target);
  243. valid_total <<= 1;
  244. break;
  245. case '1' :
  246. char_array_from_ndr (source,
  247. 0,
  248. valid_total,
  249. (unsigned char *)target);
  250. break;
  251. case 'b' :
  252. byte_array_from_ndr(source,
  253. 0,
  254. valid_total,
  255. target);
  256. break;
  257. default :
  258. continue;
  259. }
  260. target = (void *)((ULONG_PTR)target + valid_total);
  261. break;
  262. case 'z' :
  263. long_from_ndr(source, &valid_total);
  264. *((int *)target - 1) = (int) valid_total;
  265. switch ( *format++ )
  266. {
  267. case '2' :
  268. short_array_from_ndr(source,
  269. 0,
  270. valid_total,
  271. (unsigned short *)target);
  272. valid_total <<= 1;
  273. break;
  274. case '1' :
  275. byte_array_from_ndr(source,
  276. 0,
  277. valid_total,
  278. target);
  279. break;
  280. }
  281. target = (void *)((ULONG_PTR)target + valid_total);
  282. break;
  283. case 'p' :
  284. source->Buffer = (void *) ALIGN4(source->Buffer);
  285. target = (void *) ALIGN(target,pack4);
  286. source->Buffer = (void *)((ULONG_PTR)source->Buffer + 4);
  287. target = (void *)((ULONG_PTR)target + 4);
  288. break;
  289. case '(' :
  290. // *format == '2', '4', or '8'; align = 1, 3, or 7
  291. align = *format - '0' - 1;
  292. pSource = (char *) ALIGN(pSource,align);
  293. case ')' :
  294. switch (*format++)
  295. {
  296. case '8' :
  297. pack = pack8;
  298. break;
  299. case '4' :
  300. pack = pack4;
  301. break;
  302. case '2' :
  303. pack = pack2;
  304. break;
  305. default :
  306. continue;
  307. }
  308. target = (void *) ALIGN(target,pack);
  309. break;
  310. case '8' :
  311. source->Buffer = (void *)ALIGN8(source->Buffer);
  312. break;
  313. case '4' :
  314. source->Buffer = (void *)ALIGN4(source->Buffer);
  315. break;
  316. case '2' :
  317. source->Buffer = (void *)ALIGN2(source->Buffer);
  318. break;
  319. case '1' :
  320. break;
  321. default :
  322. return;
  323. } // switch
  324. } // for
  325. } // else
  326. }
  327. void RPC_ENTRY
  328. data_into_ndr (
  329. void * source,
  330. PRPC_MESSAGE target,
  331. char * format,
  332. unsigned char MscPak)
  333. /*++
  334. Routine Description:
  335. This routine copies data into the runtime buffer.
  336. Arguments:
  337. source - Buffer of data to be marshalled into the RPC message.
  338. target - RPC message structure to be passed to the runtime.
  339. format - Format of the data.
  340. MscPak - Packing level.
  341. --*/
  342. {
  343. unsigned long valid_total;
  344. register char *pSource;
  345. register char *pTarget;
  346. unsigned long pack2, pack4, pack8;
  347. unsigned long increment;
  348. unsigned long pack, align;
  349. pSource = (char *)source;
  350. pTarget = (char *)target->Buffer;
  351. // pre-compute the possible alignment masks
  352. if ( MscPak )
  353. MscPak--;
  354. pack2 = MscPak & 0x1;
  355. pack4 = MscPak & 0x3;
  356. pack8 = MscPak & 0x7;
  357. for (;;)
  358. {
  359. switch (*format++)
  360. {
  361. case 'b' :
  362. case 'c' :
  363. *((char *)pTarget) = *((char *)pSource);
  364. pTarget += 1;
  365. pSource += 1;
  366. break;
  367. case 'w' :
  368. pTarget = (char *) ALIGN2(pTarget);
  369. pSource = (char *) ALIGN(pSource,pack2);
  370. *((short *)pTarget) = *((short *)pSource);
  371. pTarget += 2;
  372. pSource += 2;
  373. break;
  374. case 'l' :
  375. case 'f' :
  376. pTarget = (char *) ALIGN4(pTarget);
  377. pSource = (char *) ALIGN(pSource,pack4);
  378. *((long *)pTarget) = *((long *)pSource);
  379. pTarget += 4;
  380. pSource += 4;
  381. break;
  382. case 'h' :
  383. case 'd' :
  384. pTarget = (char *) ALIGN8(pTarget);
  385. pSource = (char *) ALIGN(pSource,pack8);
  386. #if defined(DOS) || defined(WIN)
  387. *((DWORD *) pTarget) = *((DWORD *) &pSource);
  388. *(((DWORD *) pTarget) + 1) = *(((DWORD *) &pSource) + 1);
  389. #else
  390. *((__int64 *)pTarget) = *((__int64 *)pSource);
  391. #endif
  392. pTarget += 8;
  393. pSource += 8;
  394. break;
  395. case 's' :
  396. pTarget = (char *) ALIGN4(pTarget);
  397. switch (*format++)
  398. {
  399. case '2' :
  400. valid_total = NdrWStrlenStrcpy((wchar_t *)(pTarget + 8),
  401. (wchar_t *)pSource);
  402. increment = valid_total << 1;
  403. break;
  404. case '1' :
  405. valid_total = NdrStrlenStrcpy(pTarget + 8,pSource);
  406. increment = valid_total;
  407. break;
  408. default :
  409. continue;
  410. }
  411. *((long *)pTarget) = 0; // offset
  412. pTarget += 4;
  413. *((long *)pTarget) = valid_total; // count
  414. pTarget += 4;
  415. pTarget += increment;
  416. pSource += increment;
  417. break;
  418. case 'z' :
  419. valid_total = (long) *((int *)pSource - 1);
  420. pTarget = (char *) ALIGN4(pTarget);
  421. *((long *)pTarget) = valid_total;
  422. pTarget += 4;
  423. if ( *format++ == '2' )
  424. valid_total <<= 1;
  425. RpcpMemoryCopy(pTarget,
  426. pSource,
  427. valid_total);
  428. pTarget += valid_total;
  429. pSource += valid_total;
  430. break;
  431. case 'p' :
  432. pTarget = (char *) ALIGN4(pTarget);
  433. pSource = (char *) ALIGN(pSource,pack4);
  434. pTarget += 4;
  435. pSource += 4;
  436. break;
  437. case '(' :
  438. // *format == '2', '4', or '8'; align = 1, 3, or 7
  439. align = *format - '0' - 1;
  440. pTarget = (char *) ALIGN(pTarget,align);
  441. case ')' :
  442. switch (*format++)
  443. {
  444. case '8' :
  445. pack = pack8;
  446. break;
  447. case '4' :
  448. pack = pack4;
  449. break;
  450. case '2' :
  451. pack = pack2;
  452. break;
  453. default :
  454. continue;
  455. }
  456. pSource = (char *) ALIGN(pSource,pack);
  457. break;
  458. case '8' :
  459. pTarget = (char *) ALIGN8(pTarget);
  460. break;
  461. case '4' :
  462. pTarget = (char *) ALIGN4(pTarget);
  463. break;
  464. case '2' :
  465. pTarget = (char *) ALIGN2(pTarget);
  466. break;
  467. case '1' :
  468. break;
  469. default :
  470. target->Buffer = pTarget;
  471. return;
  472. } // switch
  473. } // for
  474. }
  475. void RPC_ENTRY
  476. tree_into_ndr (
  477. void * source,
  478. PRPC_MESSAGE target,
  479. char * format,
  480. unsigned char MscPak)
  481. /*++
  482. Routine Description:
  483. This routine copies data into the runtime buffer.
  484. Arguments:
  485. source - Buffer of data to be marshalled into the RPC message.
  486. target - RPC message structure to be passed to the runtime.
  487. format - Format of the data.
  488. MscPak - Packing level.
  489. --*/
  490. {
  491. unsigned long valid_total;
  492. register char *pSource;
  493. register char *pTarget;
  494. unsigned long pack2, pack4, pack8;
  495. unsigned long increment;
  496. pSource = (char *)source;
  497. pTarget = (char *)target->Buffer;
  498. // pre-compute the possible alignment masks
  499. if ( MscPak )
  500. MscPak--;
  501. pack2 = MscPak & 0x1;
  502. pack4 = MscPak & 0x3;
  503. pack8 = MscPak & 0x7;
  504. for (;;)
  505. {
  506. switch (*format++)
  507. {
  508. case 'b' :
  509. case 'c' :
  510. pSource += 1;
  511. break;
  512. case 'w' :
  513. pSource = (char *) ALIGN(pSource,pack2);
  514. pSource += 2;
  515. break;
  516. case 'l' :
  517. case 'f' :
  518. pSource = (char *) ALIGN(pSource,pack4);
  519. pSource += 4;
  520. break;
  521. case 'h' :
  522. case 'd' :
  523. pSource = (char *) ALIGN(pSource,pack8);
  524. pSource += 8;
  525. break;
  526. case 's' :
  527. pSource = (char *) ALIGN(pSource,pack4);
  528. if ( ! *(void **)pSource )
  529. {
  530. pSource += 4;
  531. format++;
  532. break;
  533. }
  534. pTarget = (char *) ALIGN4(pTarget);
  535. switch (*format++)
  536. {
  537. case '2' :
  538. valid_total = NdrWStrlenStrcpy((wchar_t *)(pTarget+12),
  539. *(wchar_t **)pSource);
  540. increment = valid_total << 1;
  541. break;
  542. case '1' :
  543. valid_total = NdrStrlenStrcpy(pTarget + 12,
  544. *(char **)pSource);
  545. increment = valid_total;
  546. break;
  547. default :
  548. continue;
  549. }
  550. *((long *)pTarget) = valid_total; // max count
  551. pTarget += 4;
  552. *((long *)pTarget) = 0; // offset
  553. pTarget += 4;
  554. *((long *)pTarget) = valid_total; // actual count
  555. pTarget += 4;
  556. pSource += 4;
  557. pTarget += increment;
  558. break;
  559. case 'z' :
  560. pSource = (char *) ALIGN(pSource,pack4);
  561. if ( ! *(void **)pSource )
  562. {
  563. pSource += 4;
  564. break;
  565. }
  566. valid_total = (long) *(*(int **)pSource - 1);
  567. pTarget = (char *) ALIGN4(pTarget);
  568. *((long *)pTarget) = valid_total; // max count
  569. pTarget += 4;
  570. *((long *)pTarget) = valid_total; // actual count
  571. pTarget += 4;
  572. if ( *format++ == '2' )
  573. valid_total <<= 1;
  574. RpcpMemoryCopy(pTarget,
  575. *(char **)pSource,
  576. valid_total);
  577. pSource += 4;
  578. pTarget += valid_total;
  579. break;
  580. case '(' :
  581. case ')' :
  582. switch (*format++)
  583. {
  584. case '8' :
  585. pSource = (char *) ALIGN(pSource,pack8);
  586. break;
  587. case '4' :
  588. pSource = (char *) ALIGN(pSource,pack4);
  589. break;
  590. case '2' :
  591. pSource = (char *) ALIGN(pSource,pack2);
  592. break;
  593. default :
  594. break;
  595. }
  596. break;
  597. case '8' :
  598. case '4' :
  599. case '2' :
  600. case '1' :
  601. break;
  602. default :
  603. target->Buffer = pTarget;
  604. return;
  605. } // switch
  606. } // for
  607. }
  608. void RPC_ENTRY
  609. data_size_ndr (
  610. void * source,
  611. PRPC_MESSAGE target,
  612. char * format,
  613. unsigned char MscPak)
  614. /*++
  615. Routine Description:
  616. This routine calculates the size of the runtime buffer.
  617. Arguments:
  618. source - Buffer of data to be marshalled into the RPC message.
  619. target - RPC message structure to be passed to the runtime.
  620. format - Format of the data.
  621. MscPak - Packing level.
  622. --*/
  623. {
  624. unsigned long valid_total;
  625. register char *pSource;
  626. register unsigned long targetLength;
  627. unsigned long pack2, pack4, pack8;
  628. unsigned long pack, align;
  629. pSource = (char *)source;
  630. targetLength = target->BufferLength;
  631. // pre-compute the possible alignment masks
  632. if ( MscPak )
  633. MscPak--;
  634. pack2 = MscPak & 0x1;
  635. pack4 = MscPak & 0x3;
  636. pack8 = MscPak & 0x7;
  637. for (;;)
  638. {
  639. switch (*format++)
  640. {
  641. case 'b' :
  642. case 'c' :
  643. targetLength += 1;
  644. break;
  645. case 'w' :
  646. targetLength = (unsigned long) ALIGN2(targetLength);
  647. pSource = (char *) ALIGN(pSource,pack2);
  648. targetLength += 2;
  649. pSource += 2;
  650. break;
  651. case 'l' :
  652. case 'f' :
  653. targetLength = (unsigned long) ALIGN4(targetLength);
  654. pSource = (char *) ALIGN(pSource,pack4);
  655. targetLength += 4;
  656. pSource += 4;
  657. break;
  658. case 'h' :
  659. case 'd' :
  660. targetLength = (unsigned long) ALIGN8(targetLength);
  661. pSource = (char *) ALIGN(pSource,pack8);
  662. targetLength += 8;
  663. pSource += 8;
  664. break;
  665. case 's' :
  666. switch (*format++)
  667. {
  668. case '2' :
  669. valid_total = MIDL_wchar_strlen((wchar_t *)pSource) + 1;
  670. valid_total <<= 1;
  671. break;
  672. case '1' :
  673. valid_total = strlen(pSource) + 1;
  674. break;
  675. default :
  676. continue;
  677. }
  678. targetLength = (unsigned long) ALIGN4(targetLength);
  679. // add string length plus two longs (for offset and count)
  680. targetLength += 8 + valid_total;
  681. break;
  682. case 'z' :
  683. targetLength = (unsigned long) ALIGN4(targetLength);
  684. valid_total = (long) *((int *)pSource - 1);
  685. if ( *format++ == '2' )
  686. valid_total <<= 1;
  687. // add byte string length plus one long (for count)
  688. targetLength += 4 + valid_total;
  689. break;
  690. case 'p' :
  691. targetLength = (unsigned long) ALIGN4(targetLength);
  692. pSource = (char *) ALIGN(pSource,pack4);
  693. target->Buffer = (void *)((ULONG_PTR)target->Buffer + 4);
  694. pSource += 4;
  695. break;
  696. case '(' :
  697. // *format == '2', '4', or '8'; align = 1, 3, or 7
  698. align = *format - '0' - 1;
  699. targetLength = (unsigned long) ALIGN(targetLength,align);
  700. case ')' :
  701. switch (*format++)
  702. {
  703. case '8' :
  704. pack = pack8;
  705. break;
  706. case '4' :
  707. pack = pack4;
  708. break;
  709. case '2' :
  710. pack = pack2;
  711. break;
  712. default :
  713. continue;
  714. }
  715. pSource = (char *) ALIGN(pSource,pack);
  716. break;
  717. case '8' :
  718. targetLength = (unsigned long) ALIGN8(targetLength);
  719. break;
  720. case '4' :
  721. targetLength = (unsigned long) ALIGN4(targetLength);
  722. break;
  723. case '2' :
  724. targetLength = (unsigned long) ALIGN2(targetLength);
  725. break;
  726. case '1' :
  727. break;
  728. default :
  729. target->BufferLength = targetLength;
  730. return;
  731. } // switch
  732. } // for
  733. }
  734. void RPC_ENTRY
  735. tree_size_ndr (
  736. void * source,
  737. PRPC_MESSAGE target,
  738. char * format,
  739. unsigned char MscPak)
  740. /*++
  741. Routine Description:
  742. This routine calculates the size of the runtime buffer.
  743. Arguments:
  744. source - Buffer of data to be marshalled into the RPC message.
  745. target - RPC message structure to be passed to the runtime.
  746. format - Format of the data.
  747. MscPak - Packing level.
  748. --*/
  749. {
  750. unsigned long valid_total;
  751. register char *pSource;
  752. unsigned long pack2, pack4, pack8;
  753. pSource = (char *)source;
  754. // pre-compute the possible alignment masks
  755. if ( MscPak )
  756. MscPak--;
  757. pack2 = MscPak & 0x1;
  758. pack4 = MscPak & 0x3;
  759. pack8 = MscPak & 0x7;
  760. for (;;)
  761. {
  762. switch (*format++)
  763. {
  764. case 'b' :
  765. case 'c' :
  766. pSource += 1;
  767. break;
  768. case 'w' :
  769. pSource = (char *) ALIGN(pSource,pack2);
  770. pSource += 2;
  771. break;
  772. case 'l' :
  773. case 'f' :
  774. pSource = (char *) ALIGN(pSource,pack4);
  775. pSource += 4;
  776. break;
  777. case 'h' :
  778. case 'd' :
  779. pSource = (char *) ALIGN(pSource,pack8);
  780. pSource += 8;
  781. break;
  782. case 's' :
  783. pSource = (char *) ALIGN(pSource,pack4);
  784. if ( ! *(void __RPC_FAR * __RPC_FAR *)pSource )
  785. {
  786. pSource += 4;
  787. format++;
  788. break;
  789. }
  790. switch (*format++)
  791. {
  792. case '2' :
  793. valid_total = MIDL_wchar_strlen(
  794. *(wchar_t __RPC_FAR * __RPC_FAR *)pSource)+1;
  795. valid_total <<= 1;
  796. break;
  797. case '1' :
  798. valid_total =
  799. strlen (*(char __RPC_FAR * __RPC_FAR *)pSource) + 1;
  800. break;
  801. default :
  802. continue;
  803. }
  804. target->BufferLength = (unsigned int)
  805. ALIGN4(target->BufferLength);
  806. // add string length plus 3 longs (max count, offset, and
  807. // actual count)
  808. target->BufferLength += 12 + valid_total;
  809. pSource += 4;
  810. break;
  811. case 'z' :
  812. pSource = (char *) ALIGN(pSource,pack4);
  813. if ( ! *(void __RPC_FAR * __RPC_FAR *)pSource )
  814. {
  815. pSource += 4;
  816. break;
  817. }
  818. valid_total = (long) *(*(int **)pSource - 1);
  819. if ( *format++ == '2' )
  820. valid_total <<= 1;
  821. target->BufferLength = (unsigned int)
  822. ALIGN4(target->BufferLength);
  823. // add string length plus 2 longs (max count and actual count)
  824. target->BufferLength += 8 + valid_total;
  825. pSource += 4;
  826. break;
  827. case '(' :
  828. case ')' :
  829. switch (*format++)
  830. {
  831. case '8' :
  832. pSource = (char *) ALIGN(pSource,pack8);
  833. break;
  834. case '4' :
  835. pSource = (char *) ALIGN(pSource,pack4);
  836. break;
  837. case '2' :
  838. pSource = (char *) ALIGN(pSource,pack2);
  839. break;
  840. default :
  841. break;
  842. }
  843. break;
  844. case '8' :
  845. case '4' :
  846. case '2' :
  847. case '1' :
  848. break;
  849. default :
  850. return;
  851. }
  852. }
  853. }
  854. void RPC_ENTRY
  855. tree_peek_ndr (
  856. PRPC_MESSAGE source,
  857. unsigned char ** buffer,
  858. char * format,
  859. unsigned char MscPak)
  860. /*++
  861. Routine Description:
  862. This routine peeks the runtime buffer.
  863. Arguments:
  864. source - RPC message structure passed from the runtime to the stubs.
  865. target - Buffer to receive the unmarshalled data.
  866. format - Format of the data.
  867. MscPak - Packing level.
  868. --*/
  869. {
  870. unsigned long valid_total;
  871. register unsigned char *pBuffer;
  872. unsigned long pack8;
  873. int IsString;
  874. pBuffer = *buffer;
  875. // pre-compute the possible alignment masks
  876. if ( MscPak )
  877. MscPak--;
  878. pack8 = MscPak & 0x7;
  879. IsString = (*format == 's' || *format == 'z');
  880. for (;;)
  881. {
  882. switch (*format++)
  883. {
  884. case 'b' :
  885. case 'c' :
  886. pBuffer += 1;
  887. break;
  888. case 'w' :
  889. pBuffer = (unsigned char *) ALIGN2(pBuffer);
  890. pBuffer += 2;
  891. break;
  892. case 'l' :
  893. case 'f' :
  894. pBuffer = (unsigned char *) ALIGN4(pBuffer);
  895. pBuffer += 4;
  896. break;
  897. case 'h' :
  898. case 'd' :
  899. pBuffer = (unsigned char *) ALIGN8(pBuffer);
  900. pBuffer += 8;
  901. break;
  902. case 's' :
  903. if ( ! IsString )
  904. {
  905. pBuffer = (unsigned char *) ALIGN4(pBuffer);
  906. if ( ! *(long *)pBuffer )
  907. {
  908. pBuffer += 4;
  909. format++;
  910. break;
  911. }
  912. pBuffer += 4;
  913. long_from_ndr (source, &valid_total); // max count (ignore)
  914. }
  915. long_from_ndr (source, &valid_total); // offset (ignore)
  916. long_from_ndr (source, &valid_total); // actual count
  917. // if it's a wide char string
  918. if ( *format++ == '2' )
  919. {
  920. // wide char string must be aligned on at least a
  921. // short boundary
  922. if ( ! MscPak )
  923. pack8 = 0x1;
  924. valid_total <<= 1;
  925. }
  926. source->BufferLength = (unsigned int)
  927. ALIGN(source->BufferLength,pack8);
  928. *((unsigned long *)pBuffer - 1) = source->BufferLength;
  929. source->BufferLength += valid_total;
  930. source->Buffer = (void *)((ULONG_PTR)source->Buffer + valid_total);
  931. break;
  932. case 'z' :
  933. if ( ! IsString )
  934. {
  935. pBuffer = (unsigned char *) ALIGN4(pBuffer);
  936. if ( ! *(long *)pBuffer )
  937. {
  938. pBuffer += 4;
  939. format++;
  940. break;
  941. }
  942. pBuffer += 4;
  943. long_from_ndr (source, &valid_total); // max count (ignore)
  944. }
  945. long_from_ndr (source, &valid_total); // actual count
  946. // if it's a wide byte string
  947. if ( *format++ == '2' )
  948. {
  949. // wide byte string must be aligned on at least a
  950. // short boundary
  951. if ( ! MscPak )
  952. pack8 = 0x1;
  953. valid_total <<= 1;
  954. }
  955. source->BufferLength = (unsigned int)
  956. ALIGN(source->BufferLength,pack8);
  957. *((unsigned long *)pBuffer - 1) = source->BufferLength;
  958. source->BufferLength += valid_total;
  959. source->Buffer = (void *)((ULONG_PTR)source->Buffer + valid_total);
  960. break;
  961. case '(' :
  962. switch (*format++)
  963. {
  964. case '8' :
  965. pBuffer = (unsigned char *) ALIGN8(pBuffer);
  966. break;
  967. case '4' :
  968. pBuffer = (unsigned char *) ALIGN4(pBuffer);
  969. break;
  970. case '2' :
  971. pBuffer = (unsigned char *) ALIGN2(pBuffer);
  972. break;
  973. default :
  974. break;
  975. }
  976. break;
  977. case ')' :
  978. format++;
  979. break;
  980. case '8' :
  981. pBuffer = (unsigned char *) ALIGN8(pBuffer);
  982. break;
  983. case '4' :
  984. pBuffer = (unsigned char *) ALIGN4(pBuffer);
  985. break;
  986. case '2' :
  987. pBuffer = (unsigned char *) ALIGN2(pBuffer);
  988. break;
  989. case '1' :
  990. break;
  991. default :
  992. *buffer = pBuffer;
  993. return;
  994. }
  995. }
  996. }
  997. static unsigned long NdrStrlenStrcpy ( char *pTarget,
  998. char *pSource )
  999. {
  1000. register unsigned int count;
  1001. for ( count = 1; *pTarget++ = *pSource++; count++ )
  1002. ;
  1003. return count;
  1004. }
  1005. static unsigned long NdrWStrlenStrcpy ( wchar_t *pTarget,
  1006. wchar_t *pSource )
  1007. {
  1008. register unsigned int count;
  1009. for ( count = 1; *pTarget++ = *pSource++; count++ )
  1010. ;
  1011. return count;
  1012. }