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

969 lines
24 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. intconv.c
  5. Abstract:
  6. Short and long conversion routines.
  7. Author:
  8. Dov Harel (DovH) 21-Apr-1992
  9. Environment:
  10. This code should execute in all environments supported by RPC
  11. (DOS, Win 3.X, and Win/NT as well as OS2).
  12. Comments:
  13. Split charconv.cxx into
  14. charconv.cxx - Character related conversion.
  15. intconv.cxx - Integral type conversion.
  16. dataconv.cxx - Interpretation style converstion.
  17. Revision history:
  18. Donna Liu 07-23-1992 Added LowerIndex parameter to
  19. <basetype>_array_from_ndr routines
  20. Dov Harel 08-19-1992 Added RpcpMemoryCopy ([_f]memcpy)
  21. to ..._array_from_ndr routines
  22. Ryszard Kott 06-15-1993 Added hyper support
  23. --*/
  24. #include <sysinc.h>
  25. #include <rpc.h>
  26. #include <rpcdcep.h>
  27. #include <rpcndr.h>
  28. #include <ndrlibp.h>
  29. //
  30. // Definitions from rpcndr.h
  31. //
  32. // Network Computing Architecture (NCA) definition:
  33. //
  34. // Network Data Representation: (NDR) Label format:
  35. // An unsigned long (32 bits) with the following layout:
  36. //
  37. // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  38. // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  39. // +---------------+---------------+---------------+-------+-------+
  40. // | Reserved | Reserved |Floating point | Int | Char |
  41. // | | |Representation | Rep. | Rep. |
  42. // +---------------+---------------+---------------+-------+-------+
  43. //
  44. // Where
  45. //
  46. // Reserved:
  47. //
  48. // Must be zero (0) for NCA 1.5 and NCA 2.0.
  49. //
  50. // Floating point Representation is:
  51. //
  52. // 0 - IEEE
  53. // 1 - VAX
  54. // 2 - Cray
  55. // 3 - IBM
  56. //
  57. // Int Rep. is Integer Representation:
  58. //
  59. // 0 - Big Endian
  60. // 1 - Little Endian
  61. //
  62. // Char Rep. is Character Representation:
  63. //
  64. // 0 - ASCII
  65. // 1 - EBCDIC
  66. //
  67. // #define NDR_CHAR_REP_MASK (unsigned long)0X0000000FL
  68. // #define NDR_INT_REP_MASK (unsigned long)0X000000F0L
  69. // #define NDR_FLOAT_REP_MASK (unsigned long)0X0000FF00L
  70. //
  71. // #define NDR_LITTLE_ENDIAN (unsigned long)0X00000010L
  72. // #define NDR_BIG_ENDIAN (unsigned long)0X00000000L
  73. //
  74. // #define NDR_IEEE_FLOAT (unsigned long)0X00000000L
  75. // #define NDR_VAX_FLOAT (unsigned long)0X00000100L
  76. //
  77. // #define NDR_ASCII_CHAR (unsigned long)0X00000000L
  78. // #define NDR_EBCDIC_CHAR (unsigned long)0X00000001L
  79. //
  80. // #define NDR_LOCAL_DATA_REPRESENTATION (unsigned long)0X00000010L
  81. //
  82. //
  83. // For shorts assume the following 16-bit word layout:
  84. //
  85. // 1 1 1 1 1 1
  86. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  87. // +---------------+---------------+
  88. // | A | B |
  89. // +---------------+---------------+
  90. //
  91. // For longs assume the following 32-bit word layout:
  92. //
  93. // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  94. // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  95. // +---------------+---------------+---------------+---------------+
  96. // | A | B | C | D |
  97. // +---------------+---------------+---------------+---------------+
  98. //
  99. void RPC_ENTRY
  100. short_from_ndr(
  101. IN OUT PRPC_MESSAGE SourceMessage,
  102. OUT unsigned short * Target
  103. )
  104. /*++
  105. Routine Description:
  106. Unmarshall a short from an RPC message buffer into the target
  107. (*Target). This routine:
  108. o Aligns the buffer pointer to the next (0 mod 2) boundary,
  109. o Unmarshalls the short (as unsigned short); performs data
  110. conversion if necessary, and
  111. o Advances the buffer pointer to the address immediately
  112. following the unmarshalled short.
  113. Arguments:
  114. SourceMessage - A pointer to an RPC_MESSAGE.
  115. IN - SourceMessage->Buffer points to the address just prior to
  116. the short to be unmarshalled.
  117. OUT - SourceMessage->Buffer points to the address just following
  118. the short which was just unmarshalled.
  119. Target - A pointer to the short to unmarshall the data into.
  120. Return Values:
  121. None.
  122. --*/
  123. {
  124. register unsigned char PAPI * aBuffer =
  125. (unsigned char *)SourceMessage->Buffer;
  126. aBuffer++;
  127. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~1);
  128. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  129. NDR_BIG_ENDIAN )
  130. {
  131. *(unsigned short *)Target = RtlUshortByteSwap(*(unsigned short *)aBuffer);
  132. }
  133. else
  134. {
  135. *(short *)Target = *((short *)aBuffer);
  136. }
  137. //
  138. // Update SourceMessage->Buffer before returning:
  139. //
  140. SourceMessage->Buffer = aBuffer + 2;
  141. }
  142. //
  143. // end short_from_ndr
  144. //
  145. void RPC_ENTRY
  146. short_array_from_ndr(
  147. IN OUT PRPC_MESSAGE SourceMessage,
  148. IN unsigned long LowerIndex,
  149. IN unsigned long UpperIndex,
  150. OUT unsigned short *Target
  151. )
  152. /*++
  153. Routine Description:
  154. Unmarshall an array of shorts from an RPC message buffer into
  155. the range Target[LowerIndex] .. Target[UpperIndex-1] of the
  156. target array of shorts (Target[]). This routine:
  157. o Aligns the buffer pointer to the next (0 mod 2) boundary,
  158. o Unmarshalls MemberCount shorts; performs data
  159. conversion if necessary, and
  160. o Advances the buffer pointer to the address immediately
  161. following the last unmarshalled short.
  162. Arguments:
  163. SourceMessage - A pointer to an RPC_MESSAGE.
  164. IN - SourceMessage->Buffer points to the address just prior to
  165. the first short to be unmarshalled.
  166. OUT - SourceMessage->Buffer points to the address just following
  167. the last short which was just unmarshalled.
  168. LowerIndex - Lower index into the target array.
  169. UpperIndex - Upper bound index into the target array.
  170. Target - An array of shorts to unmarshall the data into.
  171. Return Values:
  172. None.
  173. --*/
  174. {
  175. register unsigned char PAPI * aBuffer =
  176. (unsigned char *)SourceMessage->Buffer;
  177. register unsigned int index;
  178. aBuffer++;
  179. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~1);
  180. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  181. NDR_BIG_ENDIAN )
  182. {
  183. //
  184. // Big Endian Sender
  185. //
  186. for (index = (int)LowerIndex; index < UpperIndex; index++)
  187. {
  188. Target[index] = RtlUshortByteSwap(*(unsigned short *)aBuffer);
  189. aBuffer += 2;
  190. }
  191. //
  192. // Update SourceMessage->Buffer
  193. //
  194. SourceMessage->Buffer = (void PAPI *)aBuffer;
  195. }
  196. else
  197. {
  198. int byteCount = 2*(int)(UpperIndex - LowerIndex);
  199. RpcpMemoryCopy(
  200. &Target[LowerIndex],
  201. aBuffer,
  202. byteCount
  203. );
  204. //
  205. // Update SourceMessage->Buffer
  206. //
  207. SourceMessage->Buffer = (void PAPI *)(aBuffer + byteCount);
  208. }
  209. }
  210. //
  211. // end short_array_from_ndr
  212. //
  213. void RPC_ENTRY
  214. short_from_ndr_temp (
  215. IN OUT unsigned char ** source,
  216. OUT unsigned short * target,
  217. IN unsigned long format
  218. )
  219. {
  220. /*++
  221. Routine Description:
  222. Unmarshall a short from a given buffer into the target
  223. (*target). This routine:
  224. o Aligns the *source pointer to the next (0 mod 2) boundary,
  225. o Unmarshalls a short (as unsigned short); performs data
  226. conversion if necessary, and
  227. o Advances the *source pointer to the address immediately
  228. following the unmarshalled short.
  229. Arguments:
  230. source - A pointer to a pointer to a buffer
  231. IN - *source points to the address just prior to
  232. the short to be unmarshalled.
  233. OUT - *source points to the address just following
  234. the short which was just unmarshalled.
  235. target - A pointer to the short to unmarshall the data into.
  236. format - The sender data representation.
  237. Return Values:
  238. None.
  239. --*/
  240. register unsigned char PAPI * aBuffer = *source;
  241. aBuffer++;
  242. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~1);
  243. if ( (format & NDR_INT_REP_MASK) == NDR_BIG_ENDIAN )
  244. {
  245. *(unsigned short *)target = RtlUshortByteSwap(*(unsigned short *)aBuffer);
  246. }
  247. else
  248. {
  249. *(short *)target = *((short *)aBuffer);
  250. }
  251. //
  252. // Update *source (== aBuffer) before returning:
  253. //
  254. *source = aBuffer + 2;
  255. }
  256. //
  257. // end short_from_ndr_temp
  258. //
  259. void RPC_ENTRY
  260. long_from_ndr(
  261. IN OUT PRPC_MESSAGE SourceMessage,
  262. OUT unsigned long * Target
  263. )
  264. /*++
  265. Routine Description:
  266. Unmarshall a long from an RPC message buffer into the target
  267. (*Target). This routine:
  268. o Aligns the buffer pointer to the next (0 mod 4) boundary,
  269. o Unmarshalls the long (as unsigned long); performs data
  270. conversion if necessary, and
  271. o Advances the buffer pointer to the address immediately
  272. following the unmarshalled long.
  273. Arguments:
  274. SourceMessage - A pointer to an RPC_MESSAGE.
  275. IN - SourceMessage->Buffer points to the address just prior to
  276. the short to be unmarshalled.
  277. OUT - SourceMessage->Buffer points to the address just following
  278. the short which was just unmarshalled.
  279. Target - A pointer to the long to unmarshall the data into.
  280. Return Values:
  281. None.
  282. --*/
  283. {
  284. register unsigned char PAPI * aBuffer =
  285. (unsigned char *)SourceMessage->Buffer;
  286. aBuffer = aBuffer + 3;
  287. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~3);
  288. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  289. NDR_BIG_ENDIAN )
  290. {
  291. *(unsigned long *)Target = RtlUlongByteSwap(*(unsigned long *)aBuffer);
  292. }
  293. else
  294. {
  295. *(long *)Target = (*(long *)aBuffer);
  296. }
  297. //
  298. // Update SourceMessage->Buffer before returning:
  299. //
  300. SourceMessage->Buffer = aBuffer + 4;
  301. }
  302. //
  303. // end long_from_ndr
  304. //
  305. void RPC_ENTRY
  306. long_array_from_ndr(
  307. IN OUT PRPC_MESSAGE SourceMessage,
  308. IN unsigned long LowerIndex,
  309. IN unsigned long UpperIndex,
  310. OUT unsigned long * Target
  311. )
  312. /*++
  313. Routine Description:
  314. Unmarshall an array of longs from an RPC message buffer into
  315. the range Target[LowerIndex] .. Target[UpperIndex-1] of the
  316. target array of longs (Target[]). This routine:
  317. o Aligns the buffer pointer to the next (0 mod 4) boundary,
  318. o Unmarshalls MemberCount longs; performs data
  319. conversion if necessary, and
  320. o Advances the buffer pointer to the address immediately
  321. following the last unmarshalled long.
  322. Arguments:
  323. SourceMessage - A pointer to an RPC_MESSAGE.
  324. IN - SourceMessage->Buffer points to the address just prior to
  325. the first long to be unmarshalled.
  326. OUT - SourceMessage->Buffer points to the address just following
  327. the last long which was just unmarshalled.
  328. LowerIndex - Lower index into the target array.
  329. UpperIndex - Upper bound index into the target array.
  330. Target - An array of longs to unmarshall the data into.
  331. Return Values:
  332. None.
  333. --*/
  334. {
  335. register unsigned char PAPI * aBuffer =
  336. (unsigned char *)SourceMessage->Buffer;
  337. register unsigned int index;
  338. aBuffer = (unsigned char *)aBuffer + 3;
  339. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~3);
  340. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  341. NDR_BIG_ENDIAN )
  342. {
  343. for (index = (int)LowerIndex; index < UpperIndex; index++)
  344. {
  345. Target[index] = RtlUlongByteSwap(*(unsigned long *)aBuffer);
  346. aBuffer += 4;
  347. }
  348. //
  349. // Update SourceMessage->Buffer
  350. //
  351. SourceMessage->Buffer = (void PAPI *)aBuffer;
  352. }
  353. else
  354. {
  355. int byteCount = 4*(int)(UpperIndex - LowerIndex);
  356. RpcpMemoryCopy(
  357. &Target[LowerIndex],
  358. aBuffer,
  359. byteCount
  360. );
  361. //
  362. // Update SourceMessage->Buffer
  363. //
  364. SourceMessage->Buffer = (void PAPI *)(aBuffer + byteCount);
  365. }
  366. }
  367. //
  368. // end long_array_from_ndr
  369. //
  370. void RPC_ENTRY
  371. long_from_ndr_temp (
  372. IN OUT unsigned char ** source,
  373. OUT unsigned long * target,
  374. IN unsigned long format
  375. )
  376. /*++
  377. Routine Description:
  378. Unmarshall a long from a given buffer into the target
  379. (*target). This routine:
  380. o Aligns the *source pointer to the next (0 mod 2) boundary,
  381. o Unmarshalls a long (as unsigned long); performs data
  382. conversion if necessary, and
  383. o Advances the *source pointer to the address immediately
  384. following the unmarshalled long.
  385. Arguments:
  386. source - A pointer to a pointer to a buffer
  387. IN - *source points to the address just prior to
  388. the long to be unmarshalled.
  389. OUT - *source points to the address just following
  390. the long which was just unmarshalled.
  391. target - A pointer to the long to unmarshall the data into.
  392. format - The sender data representation.
  393. Return Values:
  394. None.
  395. --*/
  396. {
  397. register unsigned char PAPI * aBuffer = *source;
  398. aBuffer = (unsigned char *)aBuffer + 3;
  399. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~3);
  400. if ( (format & NDR_INT_REP_MASK) == NDR_BIG_ENDIAN )
  401. {
  402. *(unsigned long *)target = RtlUlongByteSwap(*(unsigned long *)aBuffer);
  403. }
  404. else
  405. {
  406. *(long *)target = (*(long *)aBuffer);
  407. }
  408. //
  409. // Update SourceMessage->Buffer before returning:
  410. //
  411. *source = aBuffer + 4;
  412. }
  413. //
  414. // end long_from_ndr_temp
  415. //
  416. void RPC_ENTRY
  417. enum_from_ndr(
  418. IN OUT PRPC_MESSAGE SourceMessage,
  419. OUT unsigned int * Target
  420. )
  421. /*++
  422. Routine Description:
  423. Unmarshall an int from an RPC message buffer into the target
  424. (*Target). Note: this is based on the assumption, valid in all
  425. C compilers we currently support, that "enum" is treated as an
  426. "int" by the compiler.
  427. This routine:
  428. o Aligns the buffer pointer to the next (0 mod 2) boundary,
  429. o Unmarshalls the int (as unsigned int); performs data
  430. conversion if necessary, and
  431. o Advances the buffer pointer to the address immediately
  432. following the unmarshalled int.
  433. Arguments:
  434. SourceMessage - A pointer to an RPC_MESSAGE.
  435. IN - SourceMessage->Buffer points to the address just prior to
  436. the int to be unmarshalled.
  437. OUT - SourceMessage->Buffer points to the address just following
  438. the int which was just unmarshalled.
  439. Target - A pointer to the int to unmarshall the data into.
  440. Return Values:
  441. None.
  442. --*/
  443. {
  444. register unsigned char PAPI * aBuffer =
  445. (unsigned char *)SourceMessage->Buffer;
  446. aBuffer++;
  447. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~1);
  448. //
  449. // Zeroe *Target to be on the safe side later for 32-bit
  450. // int systems!
  451. //
  452. *Target = 0;
  453. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  454. NDR_BIG_ENDIAN )
  455. {
  456. *(unsigned short *)Target = RtlUshortByteSwap(*(unsigned short *)aBuffer);
  457. }
  458. else
  459. {
  460. // The following code will copy two bytes from the wire
  461. // to the two low order bytes of (*Target) independently of
  462. // the size of int.
  463. //
  464. *(short *)Target = *((short *)aBuffer);
  465. }
  466. //
  467. // Update SourceMessage->Buffer before returning:
  468. //
  469. SourceMessage->Buffer = aBuffer + 2;
  470. }
  471. //
  472. // end enum_from_ndr
  473. //
  474. void RPC_ENTRY
  475. hyper_from_ndr(
  476. IN OUT PRPC_MESSAGE SourceMessage,
  477. // OUT unsigned hyper * Target
  478. OUT hyper * Target
  479. )
  480. /*++
  481. Routine Description:
  482. Unmarshall a hyper from an RPC message buffer into the target
  483. (*Target). This routine:
  484. o Aligns the buffer pointer to the next (0 mod 8) boundary,
  485. o Unmarshalls the hyper (as unsigned hyper); performs data
  486. conversion if necessary, and
  487. o Advances the buffer pointer to the address immediately
  488. following the unmarshalled hyper.
  489. Arguments:
  490. SourceMessage - A pointer to an RPC_MESSAGE.
  491. IN - SourceMessage->Buffer points to the address just prior to
  492. the hyper to be unmarshalled.
  493. OUT - SourceMessage->Buffer points to the address just following
  494. the hyper which was just unmarshalled.
  495. Target - A pointer to the hyper to unmarshall the data into.
  496. Return Values:
  497. None.
  498. --*/
  499. {
  500. register unsigned char PAPI * aBuffer =
  501. (unsigned char *)SourceMessage->Buffer;
  502. aBuffer = aBuffer + 7;
  503. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~7);
  504. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  505. NDR_BIG_ENDIAN )
  506. {
  507. *Target = RtlUlonglongByteSwap(*(unsigned hyper *)aBuffer);
  508. }
  509. else
  510. {
  511. *Target = *(hyper *)aBuffer;
  512. }
  513. //
  514. // Update SourceMessage->Buffer before returning:
  515. //
  516. SourceMessage->Buffer = aBuffer + 8;
  517. }
  518. //
  519. // end hyper_from_ndr
  520. //
  521. #if 0
  522. void RPC_ENTRY
  523. hyper_array_from_ndr(
  524. IN OUT PRPC_MESSAGE SourceMessage,
  525. IN unsigned long LowerIndex,
  526. IN unsigned long UpperIndex,
  527. // OUT unsigned hyper Target[]
  528. OUT hyper * Target
  529. )
  530. /*++
  531. Routine Description:
  532. Unmarshall an array of hypers from an RPC message buffer into
  533. the range Target[LowerIndex] .. Target[UpperIndex-1] of the
  534. target array of hypers (Target[]). This routine:
  535. o Aligns the buffer pointer to the next (0 mod 8) boundary,
  536. o Unmarshalls MemberCount hypers; performs data
  537. conversion if necessary, and
  538. o Advances the buffer pointer to the address immediately
  539. following the last unmarshalled hyper.
  540. Arguments:
  541. SourceMessage - A pointer to an RPC_MESSAGE.
  542. IN - SourceMessage->Buffer points to the address just prior to
  543. the first hyper to be unmarshalled.
  544. OUT - SourceMessage->Buffer points to the address just following
  545. the last hyper which was just unmarshalled.
  546. LowerIndex - Lower index into the target array.
  547. UpperIndex - Upper bound index into the target array.
  548. Target - An array of hypers to unmarshall the data into.
  549. Return Values:
  550. None.
  551. --*/
  552. {
  553. register unsigned char PAPI * aBuffer =
  554. (unsigned char *)SourceMessage->Buffer;
  555. register unsigned int index;
  556. aBuffer = (unsigned char *)aBuffer + 7;
  557. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~7);
  558. if ( (SourceMessage->DataRepresentation & NDR_INT_REP_MASK) ==
  559. NDR_BIG_ENDIAN )
  560. {
  561. for (index = (int)LowerIndex; index < UpperIndex; index++)
  562. {
  563. //.. We are doing ABCDEFGH -> HGFEDCBA
  564. //.. We start with ABCD going as DCBA into second word of Target
  565. //
  566. // Swap bytes:
  567. //
  568. // First apply the transformation: ABCD => BADC
  569. //
  570. *(unsigned long *)Target =
  571. (*(unsigned long *)aBuffer & MASK_A_C_) >> 8 |
  572. (*(unsigned long *)aBuffer & MASK__B_D) << 8 ;
  573. //
  574. // Now swap the left and right halves of the Target long word
  575. // achieving full swap: BADC => DCBA
  576. //
  577. //.. Put it into second word, without changing Target pointer yet.
  578. *((unsigned long *)Target + 1) =
  579. (*(unsigned long *)Target & MASK_AB__) >> 16 |
  580. (*(unsigned long *)Target & MASK___CD) << 16 ;
  581. //.. What's left is EFGH going into first word at Target
  582. //.. Compiler can't do this: ((long *)aBuffer)++;
  583. aBuffer += 4;
  584. // Swap bytes:
  585. //
  586. // First apply the transformation: EFGH => FEHG
  587. //
  588. *(unsigned long *)Target =
  589. (*(unsigned long *)aBuffer & MASK_A_C_) >> 8 |
  590. (*(unsigned long *)aBuffer & MASK__B_D) << 8 ;
  591. //
  592. // Now swap the left and right halves of the Target long word
  593. // achieving full swap: FEHG => HGFE
  594. //
  595. //.. Put it into first word, at the Target pointer
  596. *(unsigned long *)Target =
  597. (*(unsigned long *)Target & MASK_AB__) >> 16 |
  598. (*(unsigned long *)Target & MASK___CD) << 16 ;
  599. //.. Loop, advance pointers.
  600. Target++;
  601. aBuffer += 4; //.. ((long *)aBuffer)++;
  602. }
  603. //
  604. // Update SourceMessage->Buffer
  605. //
  606. SourceMessage->Buffer = (void PAPI *)aBuffer;
  607. }
  608. else
  609. {
  610. int byteCount = 8*(int)(UpperIndex - LowerIndex);
  611. RpcpMemoryCopy(
  612. &Target[LowerIndex],
  613. aBuffer,
  614. byteCount
  615. );
  616. //
  617. // Update SourceMessage->Buffer
  618. //
  619. SourceMessage->Buffer = (void PAPI *)(aBuffer + byteCount);
  620. }
  621. }
  622. //
  623. // end long_array_from_ndr
  624. //
  625. void RPC_ENTRY
  626. hyper_from_ndr_temp (
  627. IN OUT unsigned char ** source,
  628. // OUT unsigned hyper * Target,
  629. OUT hyper * Target,
  630. IN unsigned long format
  631. )
  632. /*++
  633. Routine Description:
  634. Unmarshall a hyper from a given buffer into the target
  635. (*target). This routine:
  636. o Aligns the *source pointer to the next (0 mod 2) boundary,
  637. o Unmarshalls a hyper (as unsigned hyper); performs data
  638. conversion if necessary, and
  639. o Advances the *source pointer to the address immediately
  640. following the unmarshalled hyper.
  641. Arguments:
  642. source - A pointer to a pointer to a buffer
  643. IN - *source points to the address just prior to
  644. the hyper to be unmarshalled.
  645. OUT - *source points to the address just following
  646. the hyper which was just unmarshalled.
  647. Target - A pointer to the hyper to unmarshall the data into.
  648. format - The sender data representation.
  649. Return Values:
  650. None.
  651. --*/
  652. {
  653. register unsigned char PAPI * aBuffer = *source;
  654. aBuffer = (unsigned char *)aBuffer + 3;
  655. aBuffer = (unsigned char *)((ULONG_PTR) aBuffer & ~3);
  656. if ( (format & NDR_INT_REP_MASK) == NDR_BIG_ENDIAN )
  657. {
  658. //.. We are doing ABCDEFGH -> HGFEDCBA
  659. //.. We start with ABCD going as DCBA into second word of Target
  660. //
  661. // Swap bytes:
  662. //
  663. // First apply the transformation: ABCD => BADC
  664. //
  665. *(unsigned long *)Target =
  666. (*(unsigned long *)aBuffer & MASK_A_C_) >> 8 |
  667. (*(unsigned long *)aBuffer & MASK__B_D) << 8 ;
  668. //
  669. // Now swap the left and right halves of the Target long word
  670. // achieving full swap: BADC => DCBA
  671. //
  672. //.. and put it into second word, without changing Target pointer
  673. *((unsigned long *)Target + 1) =
  674. (*(unsigned long *)Target & MASK_AB__) >> 16 |
  675. (*(unsigned long *)Target & MASK___CD) << 16 ;
  676. //.. What's left is EFGH going into first word at Target
  677. //.. Compiler can't do this: ((long *)aBuffer)++;
  678. aBuffer += 4;
  679. // Swap bytes:
  680. //
  681. // First apply the transformation: EFGH => FEHG
  682. //
  683. *(unsigned long *)Target =
  684. (*(unsigned long *)aBuffer & MASK_A_C_) >> 8 |
  685. (*(unsigned long *)aBuffer & MASK__B_D) << 8 ;
  686. //
  687. // Now swap the left and right halves of the Target long word
  688. // achieving full swap: FEHG => HGFE
  689. //
  690. //.. Put it into the first word, at the original Target pointer.
  691. *(unsigned long *)Target =
  692. (*(unsigned long *)Target & MASK_AB__) >> 16 |
  693. (*(unsigned long *)Target & MASK___CD) << 16 ;
  694. }
  695. else
  696. {
  697. //.. Copy hyper as two longs, don't change Target pointer.
  698. //.. Advance aBuffer by a long though to get the same as from above.
  699. //.. Compiler can't do this: ((long *)aBuffer)++;
  700. *(unsigned long *)Target = (*(unsigned long *)aBuffer);
  701. aBuffer += 4;
  702. *((unsigned long *)Target + 1) = (*(unsigned long *)aBuffer);
  703. }
  704. //
  705. // Update SourceMessage->Buffer before returning:
  706. //
  707. *source = aBuffer + 4;
  708. }
  709. //
  710. // end hyper_from_ndr_temp
  711. //
  712. #endif