TYPECVT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:31k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1993-1997 Microsoft Corporation
  3. Module Name:
  4.     typecvt.c
  5. Abstract:
  6.     Routines for generically converting between structure formats without
  7.     regard to alignment boundries.
  8. --*/
  9. #include "windows.h"
  10. #include <windowsx.h>
  11. #include "typecvt.h"
  12. // We want to assert errors for now.
  13. #define ASSERT_ERRORS
  14. #ifdef ASSERT_ERRORS
  15. int sprintf ();
  16. #endif
  17. //
  18. // For lack of any place better to put a general description of the type
  19. // conversion functions, The following will attempt to explain what is
  20. // needed set up for, and use, the functions.
  21. //
  22. // The main purpose of these functions is to convert non-aligned structures
  23. // to aligned structures and back again.
  24. //
  25. // In order to convert bewteen two structures it is first necessary to define
  26. // what each one looks like.  This is done most easily by statically allocating
  27. // and array of StructDefineInfo or SDI structures.  Here is an example:
  28. //
  29. //      The two structures
  30. //      struct                          struct
  31. //      {                               {
  32. //          CHAR    chElem1;                LONG    rglElem2 [10];
  33. //          WORD    rgwElem2 [5];           ULONG   ulElem1;
  34. //      } src;                          } dest;
  35. //      could be described by.
  36. //
  37. //      SDI  rgsdiSrcStructDef [] = {
  38. //          { sizeof (CHAR), sizeof (src.chElem1) },
  39. //          { sizeof (WORD), sizeof (src.rgwElem2) },
  40. //          { 0, 0 } };
  41. //
  42. //      SDI  rgsdiDestStructDef [] = {
  43. //          { sizeof (LONG), sizeof (dest.rglElem2) },
  44. //          { sizeof (ULONG), sizeof (dest.ulElem1) },
  45. //          { 0, 0 } };
  46. //
  47. // Once both structures have been defined the conversion between the structures
  48. // in different alignments and endian types can be performed with
  49. // PerformConversion ().
  50. //
  51. // For an example of how this is implemented see Fontcvt.c
  52. //
  53. //
  54. // An advantage of the conversions routines is that they are a portable
  55. // method of handling machines with Big Endian integer storage.  See header
  56. // file typecvt.h for complete description of big and little endian.
  57. //
  58. // The folowing variables are used to select the endian type of the source
  59. // and the destination structures.  The default is Little Endian.
  60. // Also, these are not meant to be accessed outside of this module.
  61. // Routines have been defined to access these.
  62. //
  63. INT vfFileEndianType = CVT_FILE_ENDIAN_DEFAULT;
  64. INT vfSysEndianType  = CVT_ENDIAN_UNKNOWN; // Set to unknown.
  65. LONG
  66. lCalculateStructOffsets (
  67.       PSDI    rgsdiStructDefine,
  68.       INT     fAlignmentType,
  69.    INT cSizeOfStruct
  70.     )
  71. /*++
  72. Routine Description:
  73.     This function is used to calculate the offsets of each element in the
  74.     Struct Define Info array.  These values are stored back int the SDI array
  75.     which was passed to us.  The offsets are based on the alignment type
  76.     sent to this routine.  It will also return the sizeof that structure as
  77.     it would be with the alignment or -1 if there is an error.
  78. Arguments:
  79.     rgsdiStruceDefine   - Definition of this structure as an array of SDI
  80.                           structures.  Note, see beginning of this file for
  81.                           a complete description of how to define this
  82.                           structure.
  83.     fAlignmentType      - This is an optional parameter which can be used to
  84.                           request the count of bytes for a particular alignment
  85.   CVT_ALIGN_PACKED - Return the sizeof the structure
  86. if the alignment were packed.
  87.   CVT_ALIGN_WORD   - Return the sizeof the structure
  88. if the alignment were WORD aligned.
  89.   CVT_ALIGN_DWORD  - Return the sizeof the structure
  90. if the alignment were DWORD aligned.
  91.   Zero or any other value, return 0 on success.
  92. cSizeOfStruct     - This value is used only for error detection.
  93.   It should be the size of the structure you are
  94.   converting in the current system alignment.
  95.   (ex. sizeof (FontHeaderType)).  The function will
  96.   compare this to it's calculate offset and return
  97.   an error if they differ.
  98.   Note that if this value is 0, no error checking will
  99.   be performed.
  100. Return Value:
  101.     Postitive Value = The total size of the structure we are looking at.
  102.             This should be the same as if we did a sizeof (struct) in the
  103.             proper alignment.
  104.     -1 = There was an error with the definition of the structure.
  105.             Here is how errors are detected.  Along with determining all of
  106.             the offsets in the specified alignment type, it will also do it
  107.             in CVT_ALIGN_SYSTEM.  If the system alignment does not match the
  108.             initial offsets, an error is reported.
  109. --*/
  110. {
  111.     LONG   oPackedOffset = 0;     // Counter for packed offset.
  112.     LONG   oWordOffset = 0;      // Counter for WORD aligned offset.
  113.     LONG   oDWordOffset = 0;      // Counter for DWORD aligned offset.
  114. //
  115. // Make sure that the system endian type has been computed.
  116. // We will probably need this for calls to PerformConversion.
  117. //
  118. if (vfSysEndianType == CVT_ENDIAN_UNKNOWN) {
  119. vfSysEndianType = fDetermineSysEndianType ();
  120. }
  121.     //
  122.     // Keep looping while there are defined elements.
  123.     //
  124.     while (rgsdiStructDefine->cTypeSize) {
  125.         //
  126.         // Make sure we are aligned to either the type boundry or the
  127.         // alignment count, whichever is smaller.
  128.         //
  129. if (rgsdiStructDefine->cTypeSize >= 2) {
  130. oWordOffset += (oWordOffset & 1); // Make sure both are on
  131. oDWordOffset += (oDWordOffset & 1); // a WORD boundry.
  132. }
  133. if (rgsdiStructDefine->cTypeSize >= 4) {
  134. // Add 2 to the DWORD alignment if it is not on a DWORD boundry.
  135. // Note that the previous check would already have WORD aligned it.
  136. oDWordOffset += (oDWordOffset & 2);
  137. }
  138.         //
  139.         // Store the offset to that element within the structure itsself.
  140.         //
  141.         rgsdiStructDefine->oPackedAlign = oPackedOffset;
  142.         rgsdiStructDefine->oWordAlign = oWordOffset;
  143.         rgsdiStructDefine->oDWordAlign = oDWordOffset;
  144.         //
  145.         // Increase by actual size of the element.
  146.         //
  147.         oPackedOffset += rgsdiStructDefine->cActualSize;
  148.         oWordOffset += rgsdiStructDefine->cActualSize;
  149.         oDWordOffset += rgsdiStructDefine->cActualSize;
  150.         rgsdiStructDefine++;
  151.     }
  152.     //
  153.     // Be sure that the structure fits within alignement.
  154. // Add word and DWORD padding accordingly.
  155.     //
  156. oWordOffset  += (oWordOffset & 1);
  157. oDWordOffset += (oDWordOffset & 1);
  158. oDWordOffset += (oDWordOffset & 2);
  159.     //
  160.     // Check to see if we successfully reached the end of the structure array.
  161. // We assume that they have sent us a sizeof(struct) in system alignment.
  162.     // If not then return an error, -1.  Otherwise, everything is fine so
  163.     // return the sizeof the structure we just got.
  164. // Note we only do it if they have given us something to compare.
  165.     //
  166. if (cSizeOfStruct) {
  167. switch (CVT_ALIGN_SYSTEM) {
  168. case CVT_ALIGN_PACKED:
  169. if (cSizeOfStruct != oPackedOffset) {
  170. return (-1);
  171. }
  172. break;
  173. case CVT_ALIGN_WORD:
  174. if (cSizeOfStruct != oWordOffset) {
  175. return (-1);
  176. }
  177. break;
  178. case CVT_ALIGN_DWORD:
  179. if (cSizeOfStruct != oDWordOffset) {
  180. return (-1);
  181. }
  182. break;
  183. }
  184. }
  185. //
  186. // Check and see what type of stucture they want us to return to
  187. // them.  Generally on NT it will be the packed value they want.
  188. //
  189. switch (fAlignmentType) {
  190. case CVT_ALIGN_PACKED:
  191. return (oPackedOffset);
  192. case CVT_ALIGN_WORD:
  193. return (oWordOffset);
  194. break;
  195. case CVT_ALIGN_DWORD:
  196. return (oDWordOffset);
  197. break;
  198. default:
  199. return (0);
  200. }
  201. }
  202. VOID
  203. vPerformConversion (
  204.      PSDI    rgsdiStructDefine,
  205.      PBYTE   pjSrcBuffer,
  206.  INT fSrcAlignment,
  207.  INT fSrcEndianType,
  208.      PBYTE   pjDestBuffer,
  209.  INT fDestAlignment,
  210.  INT fDestEndianType
  211.     )
  212. /*++
  213. Routine Description:
  214. WARNING: CalcStructureOffsets must have previously been called with
  215. rgsdiStructDesc as it's argument.
  216.     This function is the heart of the generic conversion system.  It steps
  217.     through the (PSDI) structure definition array and converts each element
  218. from the source buffer to the destination buffer.  To do this it uses the
  219. precomputed offset information stored in the structure definition.
  220. Also, if the source endian type is different from the destination, it
  221. will swap all data in the transfer.
  222. Arguments:
  223.     rgsdiStruceDefine   - Definition of this structure as an array of SDI
  224.                           structures.  Note, see beginning of this file for
  225.                           a complete description of how to define this
  226.                           structure.
  227.     pjSrcBuffer         - This is a pointer to the source strucure in memory.
  228.                           This structure does not need to be aligned.
  229.     fSrcAlignment       - This is the alignment of the source structure.
  230.   The permissible values of this field are:
  231. CVT_ALIGN_PACKED - structure is packed.
  232. CVT_ALIGN_WORD   - structure is WORD aligned.
  233. CVT_ALIGN_DWORD  - structure is DWORD aligned.
  234. CVT_ALIGN_SYSTEM - use system default alignment.
  235.     fSrcEndianType      - This is the byte ordering of the source data.
  236.   The permissible values of this field are:
  237. CVT_LITTLE_ENDIAN - data is little endian format.
  238. CVT_BIG_ENDIAN    - data is big endian format.
  239. CVT_ENDIAN_FILE   - use current file endian type.
  240. CVT_ENDIAN_SYSTEM - use current system endian type.
  241.     pjDestBuffer        - This is a pointer to the destination structure.
  242.                           This structure does not need to be aligned.
  243.     fDestAlignment      - This is the alignment of the source structure.
  244.   The permissible values of this field: Same as above.
  245.     fDestEndianType     - This is the byte ordering of the source data.
  246.   The permissible values of this field: Same as above.
  247. Return Value:
  248.     None.  Any detectable errors would have been found in the initialization
  249.     of the SDI structure.
  250. --*/
  251. {
  252. register PSDI rgsdiStrDef = rgsdiStructDefine;
  253. INT   *poSrcAlign;
  254. INT   *poDestAlign;
  255. PBYTE   pjSrc;
  256. PBYTE   pjDest;
  257. //
  258. // Get the alignment pointers set to the proper offset into the
  259. // structure.  Here is the general trick we use here.  First we set the
  260. // offset pointer to the start of the structure array.  We then find out
  261. // what offset into that structure will point us to the alignment type
  262. // we want.  After that, since we have an array we just add the sizeof
  263. // the SDI struct to the pointer and it will give us the next offset.
  264. //
  265. poSrcAlign = (INT *)rgsdiStrDef;
  266. switch (fSrcAlignment) {
  267. case CVT_ALIGN_PACKED:
  268. ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oPackedAlign -
  269. (CHAR *)rgsdiStrDef);
  270. break;
  271. case CVT_ALIGN_WORD:
  272. ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oWordAlign -
  273. (CHAR *)rgsdiStrDef);
  274. break;
  275. case CVT_ALIGN_DWORD:
  276. ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oDWordAlign -
  277. (CHAR *)rgsdiStrDef);
  278. break;
  279. }
  280. //
  281. // Same with dest.
  282. //
  283. poDestAlign = (INT *)rgsdiStrDef;
  284. switch (fDestAlignment) {
  285. case CVT_ALIGN_PACKED:
  286. ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oPackedAlign -
  287. (CHAR *)rgsdiStrDef);
  288. break;
  289. case CVT_ALIGN_WORD:
  290. ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oWordAlign -
  291. (CHAR *)rgsdiStrDef);
  292. break;
  293. case CVT_ALIGN_DWORD:
  294. ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oDWordAlign -
  295. (CHAR *)rgsdiStrDef);
  296. break;
  297. }
  298. if (fSrcEndianType == fDestEndianType) {
  299. INT cTotalCount;
  300. //
  301. // Keep converting while there exists elements with a valid convert
  302. // structure.
  303. //
  304. while (rgsdiStrDef->cTypeSize) {
  305. //
  306. // Store the actual size we need to transfer.  Also, store the
  307. // pointers to the offsets within the current structures.
  308. //
  309. cTotalCount = rgsdiStrDef->cActualSize;
  310. pjSrc = pjSrcBuffer + *poSrcAlign;
  311. pjDest = pjDestBuffer + *poDestAlign;
  312. //
  313. // MemCpy the bytes, probably faster to do it inline.
  314. //
  315. while (cTotalCount--) {
  316. *pjDest++ = *pjSrc++;
  317. }
  318. //
  319. // Now we step our three pointers to the next structure in
  320. // the array.
  321. //
  322. ((CHAR *)poSrcAlign) += sizeof (SDI);
  323. ((CHAR *)poDestAlign) += sizeof (SDI);
  324. rgsdiStrDef++;
  325. }
  326. } else {
  327. INT cArrayCount;
  328. INT cElemSize;
  329. INT wT;
  330. //
  331. // Keep converting while there exists elements with a valid convert
  332. // structure.
  333. //
  334. while (rgsdiStrDef->cTypeSize) {
  335. cArrayCount = rgsdiStrDef->cActualSize / rgsdiStrDef->cTypeSize;
  336. //
  337. // Store the actual size we need to transfer.  Also, store the
  338. // pointers to the offsets within the current structures.
  339. //
  340. cElemSize = rgsdiStrDef->cActualSize;
  341. pjSrc = pjSrcBuffer + *poSrcAlign;
  342. pjDest = pjDestBuffer + *poDestAlign;
  343. //
  344. // Handle each array element seperately.
  345. //
  346. while (cArrayCount--) {
  347. for (wT = 1; wT <= cElemSize; wT++) {
  348. //
  349. // Copy in reverse order.
  350. //
  351. *pjDest++ = *(pjSrc + (cElemSize - wT));
  352. }
  353. pjSrc += cElemSize;
  354. }
  355. //
  356. // Now we step our three pointers to the next structure in
  357. // the array.
  358. //
  359. ((CHAR *)poSrcAlign) += sizeof (SDI);
  360. ((CHAR *)poDestAlign) += sizeof (SDI);
  361. rgsdiStrDef++;
  362. }
  363. }
  364. }
  365. VOID
  366. vSetFileEndianType (
  367.     BOOL     fNewEndianType
  368.     )
  369. /*++
  370. Routine Description:
  371.     This routine is used to set the endian type of the disk file.  Normally
  372. the define CVT_FILE
  373. Arguments:
  374.     fNewEndianType   - Endian format type to set the source to.
  375.                        The only valid types are CVT_LITTLE_ENDIAN and
  376.                        CVT_BIG_ENDIAN.
  377.                        Portable calls to this function should always
  378.                        use either CVT_ENDIAN_SYSTEM or CVT_ENDIAN_FILE.
  379. Return Value:
  380.     None.
  381. --*/
  382. {
  383.     // Set the endian type of the source data.
  384.     vfFileEndianType = fNewEndianType;
  385. }
  386. INT
  387. fDetermineSysEndianType (
  388. VOID
  389.     )
  390. /*++
  391. Routine Description:
  392.     This function is used to determine how the current system stores its
  393. integers in memory.
  394. Arguments:
  395. None.
  396. Return Value:
  397. CVT_LITTLE_ENDIAN   - The system stores integers in little endian
  398.   format.  (this is 80x86 default).
  399. CVT_BIG_ENDIAN   - The system stores integers in big endian format.
  400. --*/
  401. {
  402. INT nCheckInteger;
  403. CHAR rgchTestBytes [sizeof (INT)];
  404. //
  405. // Clear the test bytes to zero.
  406. //
  407. *((INT *)rgchTestBytes) = 0;
  408. //
  409. // Set first to some value.
  410. //
  411. rgchTestBytes [0] = (CHAR) 0xFF;
  412. //
  413. // Map it to an integer.
  414. //
  415. nCheckInteger = *((INT *)rgchTestBytes);
  416. //
  417. // See if value was stored in low order of integer.
  418. // If so then system is little endian.
  419. //
  420. if (nCheckInteger == 0xFF) {
  421. return (CVT_LITTLE_ENDIAN);
  422. } else {
  423. return (CVT_LITTLE_ENDIAN);
  424. }
  425. }
  426. VOID
  427. vCharToShort (
  428.              PBYTE   pjSrc,
  429.              PBYTE   pjDest
  430.     )
  431. /*++
  432. Routine Description:
  433.     Copies the source CHAR to the destination SHORT.  Note that sign extension
  434.     is performed.  The destination buffer does not need to be WORD aligned.
  435.     This is generally used for transfering file mapped data.
  436. Arguments:
  437.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  438.     pjDest      - Returns the copied SHORT at the location pointed to.
  439. Return Value:
  440.     None.
  441. --*/
  442. {
  443.     // Get the source CHAR and use it as an argument for destination SHORT.
  444.     vDestBuffFromSHORT (
  445.              (SHORT)*pjSrc,
  446.              pjDest
  447.             );
  448. }
  449. VOID
  450. vCharToUShort (
  451.              PBYTE   pjSrc,
  452.              PBYTE   pjDest
  453.     )
  454. /*++
  455. Routine Description:
  456.     Copies the source CHAR to the destination USHORT.  Note that sign
  457.     extension is not perfomed.  The destination buffer does not need to be
  458.     WORD aligned. This is generally used for transfering file mapped data.
  459. Arguments:
  460.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  461.     pjDest      - Returns the copied SHORT at the location pointed to.
  462. Return Value:
  463.     None.
  464. --*/
  465. {
  466.     // Get the source CHAR and use it as an argument for destination USHORT.
  467.     vDestBuffFromUSHORT (
  468.              (USHORT)*pjSrc,
  469.              pjDest
  470.             );
  471. }
  472. VOID
  473. vCharToLong (
  474.              PBYTE   pjSrc,
  475.              PBYTE   pjDest
  476.     )
  477. /*++
  478. Routine Description:
  479.     Copies the source CHAR to the destination LONG.  Note that sign extension
  480.     is performed.  The destination buffer does not need to be DWORD aligned.
  481.     This is generally used for transfering file mapped data.
  482. Arguments:
  483.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  484.     pjDest      - Returns the copied LONG at the location pointed to.
  485. Return Value:
  486.     None.
  487. --*/
  488. {
  489.     // Get the source CHAR and use it as an argument for destination LONG.
  490.     vDestBuffFromLONG (
  491.              (LONG)*pjSrc,
  492.              pjDest
  493.             );
  494. }
  495. VOID
  496. vCharToULong (
  497.              PBYTE   pjSrc,
  498.              PBYTE   pjDest
  499.     )
  500. /*++
  501. Routine Description:
  502.     Copies the source CHAR to the destination ULONG.  Note that sign extension
  503.     is not performed.  The destination buffer does not need to be DWORD
  504.     aligned. This is generally used for transfering file mapped data.
  505. Arguments:
  506.     pjSrc       - Supplies pointer to the source buffer containing a CHAR.
  507.     pjDest      - Returns the copied ULONG at the location pointed to.
  508. Return Value:
  509.     None.
  510. --*/
  511. {
  512.     // Get the source CHAR and use it as an argument for destination ULONG.
  513.     vDestBuffFromULONG (
  514.              (ULONG)*pjSrc,
  515.              pjDest
  516.             );
  517. }
  518. VOID
  519. vShortToShort (
  520.              PBYTE   pjSrc,
  521.              PBYTE   pjDest
  522.     )
  523. /*++
  524. Routine Description:
  525.     Copies the source SHORT to the destination SHORT.  Neither buffers need
  526.     to be WORD aligned.  This is generally used for transfering file mapped
  527.     data.
  528. Arguments:
  529.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  530.     pjDest      - Returns the copied SHORT at the location pointed to.
  531. Return Value:
  532.     None.
  533. --*/
  534. {
  535.     // Get the source SHORT and use it as an argument for destination SHORT.
  536.     vDestBuffFromSHORT (
  537.              sSHORTFromSrcBuff (pjSrc),
  538.              pjDest
  539.             );
  540. }
  541. VOID
  542. vShortToLong (
  543.              PBYTE   pjSrc,
  544.              PBYTE   pjDest
  545.     )
  546. /*++
  547. Routine Description:
  548.     Copies the source SHORT to the destination LONG.  Note that sign extension
  549.     is perfomed.  Neither buffers need to be WORD or DWORD aligned.
  550.     This is generally used for transfering file mapped data.
  551. Arguments:
  552.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  553.     pjDest      - Returns the copied LONG at the location pointed to.
  554. Return Value:
  555.     None.
  556. --*/
  557. {
  558.     // Get the source SHORT and use it as an argument for destination LONG.
  559.     vDestBuffFromLONG (
  560.              (LONG)sSHORTFromSrcBuff (pjSrc),
  561.              pjDest
  562.             );
  563. }
  564. VOID
  565. vShortToULong (
  566.              PBYTE   pjSrc,
  567.              PBYTE   pjDest
  568.     )
  569. /*++
  570. Routine Description:
  571.     Copies the source SHORT to the destination ULONG.  Note that sign extension
  572.     is perfomed.  Neither buffers need to be WORD or DWORD aligned.
  573.     This is generally used for transfering file mapped data.
  574. Arguments:
  575.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  576.     pjDest      - Returns the copied ULONG at the location pointed to.
  577. Return Value:
  578.     None.
  579. --*/
  580. {
  581.     // Get the source SHORT and use it as an argument for destination ULONG.
  582.     vDestBuffFromULONG (
  583.              (LONG)sSHORTFromSrcBuff (pjSrc),
  584.              pjDest
  585.             );
  586. }
  587. VOID
  588. vLongToLong (
  589.              PBYTE   pjSrc,
  590.              PBYTE   pjDest
  591.     )
  592. /*++
  593. Routine Description:
  594.     Copies the source LONG to the destination LONG.  Neither buffers need to
  595.     be WORD or DWORD aligned. This is generally used for transfering file
  596.     mapped data.
  597. Arguments:
  598.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  599.     pjDest      - Returns the copied LONG at the location pointed to.
  600. Return Value:
  601.     None.
  602. --*/
  603. {
  604.     // Get the source LONG and use it as an argument for destination LONG.
  605.     vDestBuffFromLONG (
  606.              (LONG)lLONGFromSrcBuff (pjSrc),
  607.              pjDest
  608.             );
  609. }
  610. VOID
  611. vLongToShort (
  612.              PBYTE   pjSrc,
  613.              PBYTE   pjDest
  614.     )
  615. /*++
  616. Routine Description:
  617.     Copies the source LONG to the destination SHORT.  Neither buffers need to
  618.     be WORD or DWORD aligned. This is generally used for transfering file
  619.     mapped data.
  620. Arguments:
  621.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  622.     pjDest      - Returns the copied SHORT at the location pointed to.
  623. Return Value:
  624.     None.
  625. --*/
  626. {
  627.     // Get the source LONG and use it as an argument for destination SHORT.
  628.     vDestBuffFromSHORT (
  629.              (SHORT)lLONGFromSrcBuff (pjSrc),
  630.              pjDest
  631.             );
  632. }
  633. VOID
  634. vLongToChar (
  635.              PBYTE   pjSrc,
  636.              PBYTE   pjDest
  637.     )
  638. /*++
  639. Routine Description:
  640.     Copies the source LONG to the destination CHAR.  Neither buffers need to
  641.     be WORD or DWORD aligned. This is generally used for transfering file
  642.     mapped data.
  643. Arguments:
  644.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  645.     pjDest      - Returns the copied CHAR at the location pointed to.
  646. Return Value:
  647.     None.
  648. --*/
  649. {
  650.     // Get the source LONG and use it as an argument for destination CHAR.
  651. *pjDest = (CHAR)lLONGFromSrcBuff (pjSrc);
  652. }
  653. VOID
  654. vShortToChar (
  655.              PBYTE   pjSrc,
  656.              PBYTE   pjDest
  657.     )
  658. /*++
  659. Routine Description:
  660.     Copies the source SHORT to the destination CHAR.  Neither buffers need to
  661.     be WORD or DWORD aligned. This is generally used for transfering file
  662.     mapped data.
  663. Arguments:
  664.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  665.     pjDest      - Returns the copied CHAR at the location pointed to.
  666. Return Value:
  667.     None.
  668. --*/
  669. {
  670.     // Get the source SHORT and use it as an argument for destination CHAR.
  671. *pjDest = (CHAR)sSHORTFromSrcBuff (pjSrc);
  672. }
  673. SHORT
  674. sSHORTFromSrcBuff (
  675.          PBYTE   pjSrc
  676.     )
  677. /*++
  678. Routine Description:
  679.     Copies two byte short from buffer into a signed short.  The buffer does
  680.     not need to be WORD aligned.  This is generally used for copying from
  681.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  682.     fSrcEndianType is checked before copy.
  683. Arguments:
  684.     pjSrc       - Supplies pointer to the source buffer containing a SHORT.
  685. Return Value:
  686.     Signed short which is obtained from the buffer.
  687. --*/
  688. {
  689.     SHORT   sStorage;
  690. #ifdef CVT_BIG_ENDIAN_SUPPORT
  691.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  692. #endif
  693.         sStorage = (SHORT)          // Source is little endian, shift
  694.                 (                   // the high bytes high.
  695.                  (pjSrc [1] << 8) |
  696.                  (pjSrc [0])
  697.                 );
  698. #ifdef CVT_BIG_ENDIAN_SUPPORT
  699.     } else {
  700.         sStorage = (SHORT)          // Source is big endian, shift
  701.                 (                   // the high bytes low.
  702.                  (pjSrc [0] << 8) |
  703.                  (pjSrc [1])
  704.                 );
  705.     }
  706. #endif
  707.     return (sStorage);
  708. }
  709. USHORT
  710. usUSHORTFromSrcBuff (
  711.          PBYTE   pjSrc
  712.     )
  713. /*++
  714. Routine Description:
  715.     Copies two byte short from buffer into an unsigned short.  The buffer does
  716.     not need to be WORD aligned.  This is generally used for copying from
  717.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  718.     fSrcEndianType is checked before copy.
  719. Arguments:
  720.     pjSrc       - Supplies pointer to the source buffer containing a USHORT.
  721. Return Value:
  722.     Unsigned short which is obtained from the buffer.
  723. --*/
  724. {
  725.     USHORT  usStorage;
  726. #ifdef CVT_BIG_ENDIAN_SUPPORT
  727.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  728. #endif
  729.         usStorage = (USHORT)            // Source is little endian, shift
  730.                 (                       // the high bytes high.
  731.                  (pjSrc [1] << 8) |
  732.                  (pjSrc [0])
  733.                 );
  734. #ifdef CVT_BIG_ENDIAN_SUPPORT
  735.     } else {
  736.         usStorage = (USHORT)            // Source is big endian, shift
  737.                 (                       // the high bytes low.
  738.                  (pjSrc [0] << 8) |
  739.                  (pjSrc [1])
  740.                 );
  741.     }
  742. #endif
  743.     return (usStorage);
  744. }
  745. LONG
  746. lLONGFromSrcBuff (
  747.          PBYTE   pjSrc
  748.     )
  749. /*++
  750. Routine Description:
  751.     Copies four byte long from buffer into a signed long.  The buffer does
  752.     not need to be DWORD aligned.  This is generally used for copying from
  753.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  754.     fSrcEndianType is checked before copy.
  755. Arguments:
  756.     pjSrc       - Supplies pointer to the source buffer containing a LONG.
  757. Return Value:
  758.     Signed long which is obtained from the buffer.
  759. --*/
  760. {
  761.     LONG    lStorage;
  762. #ifdef CVT_BIG_ENDIAN_SUPPORT
  763.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  764. #endif
  765.         lStorage = (LONG)               // Source is little endian, shift
  766.                 ((pjSrc [3] << 24) |    // the high bytes high.
  767.                  (pjSrc [2] << 16) |
  768.                  (pjSrc [1] << 8) |
  769.                  (pjSrc [0])
  770.                 );
  771. #ifdef CVT_BIG_ENDIAN_SUPPORT
  772.     } else {
  773.         lStorage = (LONG)               // Source is big endian, shift the
  774.                 ((pjSrc [0] << 24) |    // high bytes low.
  775.                  (pjSrc [1] << 16) |
  776.                  (pjSrc [2] << 8) |
  777.                  (pjSrc [3])
  778.                 );
  779.     }
  780. #endif
  781.     return (lStorage);
  782. }
  783. ULONG
  784. ulULONGFromSrcBuff (
  785.          PBYTE   pjSrc
  786.     )
  787. /*++
  788. Routine Description:
  789.     Copies four byte long from buffer into an unsigned long.  The buffer does
  790.     not need to be DWORD aligned.  This is generally used for copying from
  791.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  792.     fSrcEndianType is checked before copy.
  793. Arguments:
  794.     pjSrc       - Supplies pointer to the source buffer containing a ULONG.
  795. Return Value:
  796.     Unsigned long which is obtained from the buffer.
  797. --*/
  798. {
  799.     ULONG   ulStorage;
  800. #ifdef CVT_BIG_ENDIAN_SUPPORT
  801.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  802. #endif
  803.         ulStorage = (ULONG)             // Source is little endian, shift
  804.                 ((pjSrc [3] << 24) |    // the high bytes high.
  805.                  (pjSrc [2] << 16) |
  806.                  (pjSrc [1] << 8) |
  807.                  (pjSrc [0])
  808.                 );
  809. #ifdef CVT_BIG_ENDIAN_SUPPORT
  810.     } else {
  811.         ulStorage = (ULONG)             // Source is big endian, shift the
  812.                 ((pjSrc [0] << 24) |    // high bytes low.
  813.                  (pjSrc [1] << 16) |
  814.                  (pjSrc [2] << 8) |
  815.                  (pjSrc [3])
  816.                 );
  817.     }
  818. #endif
  819.     return (ulStorage);
  820. }
  821. VOID
  822. vDestBuffFromSHORT (
  823.          SHORT   sSource,
  824.          PBYTE   pjDest
  825.     )
  826. /*++
  827. Routine Description:
  828.     Copies two byte signed short into a destination buffer.  The buffer does
  829.     not need to be WORD aligned.  This is generally used for copying to
  830.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  831.     fDestEndianType is checked before copy.
  832. Arguments:
  833.     sSource     - Signed short to convert to buffer.
  834.     pjDest      - Supplies pointer to destination buffer for the USHORT.
  835. Return Value:
  836.     None.
  837. --*/
  838. {
  839. #ifdef CVT_BIG_ENDIAN_SUPPORT
  840.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  841. #endif
  842.         pjDest [0] = ((sSource) & 0xFF);
  843.         pjDest [1] = ((sSource >> 8)  & 0xFF);
  844. #ifdef CVT_BIG_ENDIAN_SUPPORT
  845.     } else {
  846.         pjDest [1] = ((sSource) & 0xFF);
  847.         pjDest [0] = ((sSource >> 8)  & 0xFF);
  848.     }
  849. #endif
  850. }
  851. VOID
  852. vDestBuffFromUSHORT (
  853.          USHORT  usSource,
  854.          PBYTE   pjDest
  855.     )
  856. /*++
  857. Routine Description:
  858.     Copies two byte unsigned short into a destination buffer.  The buffer
  859.     does not need to be WORD aligned.  This is generally used for copying to
  860.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  861.     fDestEndianType is checked before copy.
  862. Arguments:
  863.     usSource    - Unsigned short to convert to buffer.
  864.     pjDest      - Supplies pointer to destination buffer for the USHORT.
  865. Return Value:
  866.     None.
  867. --*/
  868. {
  869. #ifdef CVT_BIG_ENDIAN_SUPPORT
  870.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  871. #endif
  872.         pjDest [0] = ((usSource) & 0xFF);
  873.         pjDest [1] = ((usSource >> 8)  & 0xFF);
  874. #ifdef CVT_BIG_ENDIAN_SUPPORT
  875.     } else {
  876.         pjDest [1] = ((usSource) & 0xFF);
  877.         pjDest [0] = ((usSource >> 8)  & 0xFF);
  878.     }
  879. #endif
  880. }
  881. VOID
  882. vDestBuffFromLONG (
  883.          LONG    lSource,
  884.          PBYTE   pjDest
  885.     )
  886. /*++
  887. Routine Description:
  888.     Copies four byte long into a destination buffer.  The buffer does not
  889.     need to be DWORD aligned.  This is generally used for copying to
  890.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  891.     fDestEndianType is checked before copy.
  892. Arguments:
  893.     lSource     - Signed long to convert to buffer.
  894.     pjDest      - Supplies pointer to destination buffer for the LONG.
  895. Return Value:
  896.     None.
  897. --*/
  898. {
  899. #ifdef CVT_BIG_ENDIAN_SUPPORT
  900.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  901. #endif
  902.         pjDest [0] = ((lSource) & 0xFF);
  903.         pjDest [1] = ((lSource >> 8)  & 0xFF);
  904.         pjDest [2] = ((lSource >> 16) & 0xFF);
  905.         pjDest [3] = ((lSource >> 24) & 0xFF);
  906. #ifdef CVT_BIG_ENDIAN_SUPPORT
  907.     } else {
  908.         pjDest [3] = ((lSource) & 0xFF);
  909.         pjDest [2] = ((lSource >> 8)  & 0xFF);
  910.         pjDest [1] = ((lSource >> 16) & 0xFF);
  911.         pjDest [0] = ((lSource >> 24) & 0xFF);
  912.     }
  913. #endif
  914. }
  915. VOID
  916. vDestBuffFromULONG (
  917.          ULONG   ulSource,
  918.          PBYTE   pjDest
  919.     )
  920. /*++
  921. Routine Description:
  922.     Copies four byte long into a destination buffer.  The buffer does not
  923.     need to be DWORD aligned.  This is generally used for copying to
  924.     mapped disk files.  If CVT_BIG_ENDIAN_SUPPORT is defined then the
  925.     fDestEndianType is checked before copy.
  926. Arguments:
  927.     ulSource    - Unsigned long to convert to buffer.
  928.     pjDest      - Supplies pointer to destination buffer for the ULONG.
  929. Return Value:
  930.     None.
  931. --*/
  932. {
  933. #ifdef CVT_BIG_ENDIAN_SUPPORT
  934.     if (fSrcEndianType == CVT_LITTLE_ENDIAN) {
  935. #endif
  936.         pjDest [0] = (BYTE)((ulSource) & (ULONG)0xFF);
  937.         pjDest [1] = (BYTE)((ulSource >> 8)  & (ULONG)0xFF);
  938.         pjDest [2] = (BYTE)((ulSource >> 16) & (ULONG)0xFF);
  939.         pjDest [3] = (BYTE)((ulSource >> 24) & (ULONG)0xFF);
  940. #ifdef CVT_BIG_ENDIAN_SUPPORT
  941.     } else {
  942.         pjDest [3] = (BYTE)((ulSource) & (ULONG)0xFF);
  943.         pjDest [2] = (BYTE)((ulSource >> 8)  & (ULONG)0xFF);
  944.         pjDest [1] = (BYTE)((ulSource >> 16) & (ULONG)0xFF);
  945.         pjDest [0] = (BYTE)((ulSource >> 24) & (ULONG)0xFF);
  946.     }
  947. #endif
  948. }