sutkdeco.c
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:11k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. /* TS = none */
  2. /*
  3. **  SUTKDECO.C  --  general decompression routines for
  4. **                  Setup Toolkits.  Handles all header manipulation.
  5. */
  6. #include <io.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include <string.h>
  11. #include <dos.h>
  12. #include "sutkcomp.h"
  13.   /* global header info variables and default values */
  14. extern SHORT   vwAlgType;
  15. extern LONG    vlcbSrcLength;
  16. extern BOOL    vfChecksum;
  17. extern USHORT  vusChecksum;
  18. extern USHORT  vcbArgs;
  19. extern BYTE *  vrgbArgs;
  20. extern CHAR    vszBaseName[9];
  21. extern CHAR    vszExtension[4];
  22. extern SZ      vszText;
  23. extern USHORT  vcbText;
  24. #ifdef EAS
  25. extern CHAR    *vrgbEAs;
  26. extern CHAR    far *vfrgbEAs;
  27. extern USHORT  vuscbEAs;
  28. #endif /* EAS */
  29. #ifdef WIN2_VER
  30. extern HANDLE  vhRgbArgs;
  31. extern HANDLE  vhSzText;
  32. #endif /* WIN2_VER */
  33.   /* forward declarations of local routines */
  34. extern  SHORT   far WReadHeaderInfo(int fhSrc);
  35. extern  BOOL        FReadNBytes(int fh, BYTE *pb, int n);
  36. extern  BOOL        FReadUs(int fh, USHORT *pw);
  37. extern  BOOL        FReadUl(int fh, ULONG *pul);
  38. #ifdef ZECKFORMAT
  39. /* This is the magic value for non-split Zeck files.  Since we can't handle
  40.    Zeck split files, we don't try to understand that form of header. */
  41. #define rgbZeckMagicValue  "x53x5ax20x88xf0x27x33xd1"
  42. BOOL   vfZeckFormat = FALSE;
  43. #endif /* ZECKFORMAT */
  44. /*
  45. **  SHORT  far  WReadHeaderInfo(int fhSrc)
  46. **  
  47. **  Determine whether the given file has a header in our format, and if
  48. **  so, extract the information from it into globals.  If the 8 magic bytes
  49. **  at the beginning of the file are correct, we assume it's a compressed
  50. **  file and we give errors if something is wrong with the rest of the
  51. **  header (eg the agorithm is not a known type, or something is wrong with
  52. **  the format of the rest of the header.)  If the 8 magic bytes don't match,
  53. **  we assume it's uncompressed.
  54. **  (Notice that the file could also be uncompressed but still have a
  55. **  header.  The wAlgType in the header would be wAlgTypeNoCompress.)
  56. **  Hitting EOF in reading the magic bytes is not an error, but premature
  57. **  EOF while reading any of the rest of the header is an error.
  58. **
  59. **  Returns the algorithm type used to compress the file, or a return code
  60. **  indicating an error.  If the header is read sucessfully, this procedure
  61. **  may allocate memory to store some of the header information; the caller
  62. **  should always call FFreeHeaderInfo() after the decompression has finished.
  63. **  WReadHeaderInfo calls FFreeHeaderInfo before reading and on errors, so
  64. **  the headers of any number of files can be read and FFreeHeaderInfo need
  65. **  only be called after the last file is read.
  66. **
  67. **  Seeks fhSrc to the byte after the header, if there was a header.
  68. **  If there was no header, resets fhSrc to its original value.
  69. */
  70. SHORT  far  WReadHeaderInfo(int fhSrc)
  71. {
  72.     USHORT  us;
  73.     USHORT  cbHeader;
  74.     USHORT  usFlags;
  75.     SHORT   rcError;
  76.     LONG    libSav;
  77.     BYTE    b;
  78.     BYTE    rgb[8];
  79.     FFreeHeaderInfo();
  80.     if (fhSrc == -1)
  81.         return(rcReadError);
  82.     if ((libSav = tell(fhSrc)) == NIL)
  83.         return(rcReadSeekError);
  84.       /* read first 8 required bytes */
  85.     if (!FReadNBytes(fhSrc, rgb, 8))
  86.         {
  87.         rcError = rcNoHeader;
  88.         goto ErrorReturn;
  89.         }
  90.       /* check magic number */
  91.     for (us = 0;  us < cbMagic;  us++)
  92.         {
  93.         if (rgb[us] != (BYTE)(*(rgbMagicValue + us)))
  94.             break;
  95.         }
  96.     if (us != cbMagic)   /* magic bytes didn't match */
  97.         {
  98. #ifdef ZECKFORMAT
  99.         for (us = 0;  us < cbMagic;  us++)   /* check Zeck magic bytes */
  100.             {
  101.             if (rgb[us] != (BYTE)(*(rgbZeckMagicValue + us)))
  102.                 break;
  103.             }
  104.         if (us == cbMagic - 1)  /* only last byte is different -- split file */
  105.             {
  106.             /* Zeck split file */
  107.             rcError = rcZeckSplitFile;
  108.             goto ErrorReturn;
  109.             }
  110.         if (us == cbMagic && FReadUl(fhSrc, &vlcbSrcLength))
  111.             {
  112.             vfZeckFormat = (BOOL)TRUE;
  113.             vwAlgType = wAlgTypeZK1;
  114.             return(vwAlgType);
  115.             }
  116. #endif /* ZECKFORMAT */
  117.           /* must be an uncompressed file with no header */
  118.         rcError = rcNoHeader;
  119.         goto ErrorReturn;
  120.         }
  121.       /* read next 6 required bytes */
  122.     if (!FReadNBytes(fhSrc, rgb, 6))
  123.         goto ReadErrorReturn;
  124.       /* get algorithm type */
  125.     us = rgb[0] + (rgb[1] << 8);
  126.     /* REVIEW: this sleazy thing checks to make sure we have a valid alg type
  127.        for the flags that are currently turned on.  REWRITE THIS. */
  128.     if (FALSE
  129. #ifdef ZK1
  130.             || (us == wAlgTypeZK1)
  131. #endif /* ZK1 */
  132. #ifdef JJJ1
  133.             || (us == wAlgTypeJJJ1)
  134. #endif /* JJJ1 */
  135. #ifdef NC_XOR1
  136.             || (us == wAlgTypeNoCompress)
  137.             || (us == wAlgTypeXOR1)
  138. #endif /* NC_XOR1 */
  139.             )
  140.         vwAlgType = us;
  141.     else
  142.         {
  143.         rcError = rcUnknownAlgType;
  144.         goto ErrorReturn;
  145.         }
  146.       /* get size of header; save for later Seek */
  147.     cbHeader = rgb[2] + (rgb[3] << 8);
  148.       /* get first flag word */
  149.     usFlags = rgb[4] + (rgb[5] << 8);
  150.       /* then read the optional components that had their flags set */
  151.     if (usFlags & bmSrcLength)
  152.         {
  153.         if (!FReadUl(fhSrc, &vlcbSrcLength))
  154.             goto ReadErrorReturn;
  155.         }
  156.     if (usFlags & bmChecksum)
  157.         {
  158.         vfChecksum = (BOOL)TRUE;
  159.         if (!FReadUs(fhSrc, &vusChecksum))
  160.             goto ReadErrorReturn;
  161.         }
  162.     if (usFlags & bmArgs)
  163.         {
  164.         if (!FReadUs(fhSrc, &vcbArgs))
  165.             goto ReadErrorReturn;
  166.         if (vcbArgs == 0)
  167.             {
  168.             rcError = rcBadHeader;
  169.             goto ErrorReturn;
  170.             }
  171. #ifndef WIN2_VER
  172.         vrgbArgs = (BYTE *)malloc(vcbArgs * sizeof(BYTE));
  173. #else /* WIN2_VER */
  174.         if ((vhRgbArgs = LocalAlloc(LMEM_FIXED, vcbArgs * sizeof(BYTE)))
  175.                                                                         != NULL)
  176.             if ((vszText = (BYTE *)LocalLock(vhRgbArgs)) == NULL)
  177.                 {
  178.                 LocalFree(vhRgbArgs);
  179.                 vhRgbArgs = NULL;
  180.                 }
  181. #endif /* WIN2_VER */
  182.         if (vrgbArgs == NULL)
  183.             {
  184.             rcError = rcOutOfMemory;
  185.             goto ErrorReturn;
  186.             }
  187.         if (!FReadNBytes(fhSrc, (BYTE *)vrgbArgs, vcbArgs))
  188.             goto ReadErrorReturn;
  189.         }
  190.       /* handle filename strings */
  191.     if (usFlags & bmBaseName)
  192.         {
  193.         us = 0;
  194.         b = 'Z';
  195.         while (FReadByte(fhSrc, &b) && ((vszBaseName[us] = b) != ''))
  196.             {
  197.             if (us < 8)
  198.                 us++;
  199.             else
  200.                 {
  201.                 rcError = rcFilenamesTooLong;
  202.                 goto ErrorReturn;
  203.                 }
  204.             }
  205.         if (b != '')
  206.             goto ReadErrorReturn;
  207.         }
  208.     if (usFlags & bmExtension)
  209.         {
  210.         us = 0;
  211.         b = 'Z';
  212.         while (FReadByte(fhSrc, &b) && ((vszExtension[us] = b) != ''))
  213.             {
  214.             if (us < 3)
  215.                 us++;
  216.             else
  217.                 {
  218.                 rcError = rcFilenamesTooLong;
  219.                 goto ErrorReturn;
  220.                 }
  221.             }
  222.         if (b != '')
  223.             goto ReadErrorReturn;
  224.         }
  225.     if (usFlags & bmText)
  226.         {
  227.         if (!FReadUs(fhSrc, &vcbText))
  228.             goto ReadErrorReturn;
  229.         if (vcbText == 0)
  230.             {
  231.             rcError = rcBadHeader;
  232.             goto ErrorReturn;
  233.             }
  234. #ifndef WIN2_VER
  235.         vszText = (SZ)malloc(vcbText * sizeof(CHAR));
  236. #else /* WIN2_VER */
  237.         if ((vhSzText = LocalAlloc(LMEM_FIXED, vcbText * sizeof(CHAR))) != NULL)
  238.             if ((vszText = (SZ)LocalLock(vhSzText)) == NULL)
  239.                 {
  240.                 LocalFree(vhSzText);
  241.                 vhSzText = NULL;
  242.                 }
  243. #endif /* WIN2_VER */
  244.         if (vszText == NULL)
  245.             {
  246.             rcError = rcOutOfMemory;
  247.             goto ErrorReturn;
  248.             }
  249.         if (!FReadNBytes(fhSrc, (BYTE *)vszText, vcbText))
  250.             goto ReadErrorReturn;
  251.         }
  252. #ifdef EAS
  253.     if (usFlags & bmEAs)
  254.         {
  255.         if (!FReadNBytes(fhSrc, (BYTE *) &vuscbEAs, sizeof(USHORT)))
  256.             goto ReadErrorReturn;
  257. #ifdef OS2_VER
  258.         vfrgbEAs = _fmalloc(vuscbEAs);
  259.         if (!vfrgbEAs)
  260.             {
  261.             if (lseek(fhSrc, (LONG)vuscbEAs, SEEK_CUR) == -1)
  262.                 {
  263.                 rcError = rcReadSeekError;
  264.                 goto ErrorReturn;
  265.                 }
  266.             }
  267.         else
  268.             {
  269.             USHORT cbRead;
  270.             if (DosRead(fhSrc, vfrgbEAs, vuscbEAs, &cbRead))
  271.                 {
  272.                 _ffree(vfrgbEAs);
  273.                 vfrgbEAs = NULL;
  274.                 vuscbEAs = 0;
  275.                 goto ReadErrorReturn;
  276.                 }    
  277.             }
  278. #else
  279.         if (lseek(fhSrc, (LONG)vuscbEAs, SEEK_CUR) == -1)
  280.             {
  281.             rcError = rcReadSeekError;
  282.             goto ErrorReturn;
  283.             }
  284. #endif /* OS2_VER */
  285.         }
  286. #endif /* EAS */
  287.       /* skip any remaining header components that we don't grok */
  288.     if (lseek(fhSrc, (LONG)cbHeader, SEEK_SET) == -1)
  289.         {
  290.         rcError = rcReadSeekError;
  291.         goto ErrorReturn;
  292.         }
  293.     return(vwAlgType);
  294.     /* errors that cause jumps to here have a trashed header (ie magic
  295.        bytes were correct but something else was bad) or a read failure,
  296.        but it is not an error if header is missing entirely */
  297. ReadErrorReturn:
  298.     if (eof(fhSrc))
  299.         rcError = rcBadHeader;
  300.     else
  301.         rcError = rcReadError;
  302. ErrorReturn:
  303.     FFreeHeaderInfo();
  304.     lseek(fhSrc, libSav, SEEK_SET);
  305.     return(rcError);
  306. }
  307. /*
  308. **  BOOL  FReadNBytes(int fh, BYTE * pb, int n)
  309. **
  310. **  Reads n bytes from file handle fh into buffer pointed to by pb.
  311. **  Returns TRUE if read was sucessful, FALSE if not (or if EOF.)
  312. */
  313. BOOL  FReadNBytes(int fh, BYTE * pb, int n)
  314. {
  315.     if (read(fh, pb, n) == n)
  316.         return((BOOL)TRUE);
  317.     else
  318.         return(FALSE);
  319. }
  320. /*
  321. **  BOOL  FReadUs(int fh, USHORT * pw)
  322. **
  323. **  Reads a short word from file handle fh into word pointed to by pw.
  324. **  Returns TRUE if read was sucessful, FALSE if not (or if EOF.)
  325. */
  326. BOOL  FReadUs(int fh, USHORT * pw)
  327. {
  328.     BYTE  rgb[2];
  329.     if (FReadNBytes(fh, rgb, 2))
  330.         {
  331.         *pw = rgb[0] + (rgb[1] << 8);
  332.         return((BOOL)TRUE);
  333.         }
  334.     return(FALSE);
  335. }
  336. /*
  337. **  BOOL  FReadUl(int fh, ULONG * pul)
  338. **
  339. **  Reads a long from file handle fh into the long pointed to by pul.
  340. **  Returns TRUE if read was sucessful, FALSE if not (or if EOF.)
  341. */
  342. BOOL  FReadUl(int fh, ULONG * pul)
  343. {
  344.     BYTE   rgb[4];
  345.     ULONG  ul;
  346.     ULONG  ulShift;
  347.     if (!FReadNBytes(fh, rgb, 4))
  348.         return(FALSE);
  349.     ul = rgb[0];
  350.     ulShift = rgb[1];
  351.     ul = (ulShift << 8) + ul;
  352.     ulShift = rgb[2];
  353.     ul = (ulShift << 16) + ul;
  354.     ulShift = rgb[3];
  355.     ul = (ulShift << 24) + ul;
  356.     *pul = ul;
  357.     return((BOOL)TRUE);
  358. }