home *** CD-ROM | disk | FTP | other *** search
/ ANews 1 / AnewsCD01.iso / Indispensables / Compression / xad / Developer / Sources / clients / PackDev.c < prev    next >
C/C++ Source or Header  |  1999-08-09  |  9KB  |  304 lines

  1. #ifndef XADMASTER_PACKDEV_C
  2. #define XADMASTER_PACKDEV_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        PackDev.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: PackDev.c 1.3 (29.06.1999)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    PackDev disk archiver client
  12.  
  13.  1.0   13.06.98 : first version
  14.  1.1   13.02.99 : started again with that client
  15.  1.2   20.06.99 : removed exec.library calls
  16.  1.3   29.06.99 : now uses master free stuff
  17. */
  18.  
  19. /* For now SectorLabel information is ignored, as current
  20. xadmaster.library does not support SectorLabels. */
  21.  
  22. #include <proto/xadmaster.h>
  23. #include <devices/trackdisk.h>
  24. #include "SDI_compiler.h"
  25. #define SDI_TO_ANSI
  26. #include "SDI_ASM_STD_protos.h"
  27. #include "xpkstuff.c"
  28.  
  29. #ifndef XADMASTERFILE
  30. #define PackDev_Client        FirstClient
  31. #define NEXTCLIENT        0
  32. UBYTE version[] = "$VER: PackDev 1.3 (29.06.1999)";
  33. #endif
  34. #define PACKDEV_VERSION        1
  35. #define PACKDEV_REVISION    3
  36.  
  37. struct PackDevHead {
  38.   UBYTE        pd_Header[4];    /* equals 'PKD\x13' */
  39.   ULONG        pd_BlockNum;    /* Number of blocks */
  40.   ULONG        pd_BlockSize;    /* size of one block */
  41.   ULONG        pd_Reserved;    /* Reserved blocks */
  42.   ULONG        pd_TrackLength;    /* Length of one track*/
  43.   ULONG        pd_xpkBufferSize; /* in byte */
  44.   ULONG        pd_xpkPacker;    /* XPK packer type */
  45.   ULONG pad1;    /* These are fields containing the XPK packer name */
  46.   ULONG pad2;    /* Don't know, why the author used 24bytes instead */
  47.   ULONG pad3;    /* of the required 4. */
  48.   ULONG pad4;    /* The fields are ignored by that client */
  49.   ULONG pad5;
  50.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  51.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  52. };
  53.  
  54. struct PackDevHeadOld {
  55.   UBYTE        pd_Header[4];    /* equals 'PKD\x11' */
  56.   ULONG        pd_BlockNum;    /* Number of blocks */
  57.   ULONG        pd_BlockSize;    /* size of one block */
  58.   ULONG        pd_Reserved;    /* Reserved blocks */
  59.   ULONG        pd_TrackLength;    /* Length of one track*/
  60.   ULONG        pd_xpkBufferSize; /* in byte */
  61.   ULONG        pd_xpkPacker;    /* XPK packer type */
  62.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  63.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  64. };
  65.  
  66. /* Every block has following structure:
  67.  ULONG size
  68.  ULONG data[...]
  69.  ULONG checksum
  70.  
  71. Where data are the blocks and additionally the SectorLabels (16 Byte).
  72. NOTE: xadmaster does not support to extract the label data in current version!
  73.  
  74. Checksum is missing in PackDev11 Version.
  75. */
  76.  
  77. #define PKD_XPKPACKED    (1<<0)
  78. #define PKD_OLDMODE    (1<<1)
  79.  
  80. ASM(BOOL) PackDev_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  81. REG(a6, struct xadMasterBase *xadMasterBase))
  82. {
  83.   if(((ULONG *)data)[0] == 0x504B4413 || ((ULONG *)data)[0] == 0x504B4411)
  84.     return 1;
  85.   else
  86.     return 0;
  87. }
  88.  
  89. LONG PKDdecrBuf(STRPTR *buf, ULONG *i, struct xadArchiveInfo *ai,
  90. struct xadMasterBase *xadMasterBase, ULONG oldmode)
  91. {
  92.   LONG err, size;
  93.   if(!(err = xadHookAccess(XADAC_READ, 4, &size, ai)))
  94.   {
  95.     if(!(err = xpkDecrunch(buf, i, ai, xadMasterBase)))
  96.     {
  97.       if(!oldmode)
  98.         err = xadHookAccess(XADAC_READ, 4, &size, ai);
  99.     }
  100.   }
  101.   return err;
  102. }
  103.  
  104. /* maybe there are some errors in that code, not tested yet */
  105. ASM(LONG) PackDev_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  106. REG(a6, struct xadMasterBase *xadMasterBase))
  107. {
  108.   struct PackDevHead h;
  109.   LONG err;
  110.  
  111.   if(!(err = xadHookAccess(XADAC_READ, sizeof(struct PackDevHeadOld), &h, ai)))
  112.   {
  113.     if(h.pd_Header[3] == 0x11 || !(err = xadHookAccess(XADAC_READ,
  114.     sizeof(struct PackDevHead)-sizeof(struct PackDevHeadOld), ((STRPTR) &h) +
  115.     sizeof(struct PackDevHeadOld), ai)))
  116.     {
  117.       struct xadDiskInfo *xdi;
  118.       ULONG blksiz = 0, i, j, dat[10];
  119.       STRPTR buf = 0;
  120.  
  121.       if(h.pd_Header[3] == 0x11)
  122.       {
  123.         h.pd_KnownFileSys = ((struct PackDevHeadOld *) &h)->pd_KnownFileSys;
  124. /*      h.pd_xpkMode = ((struct PackDevHeadOld *) &h)->pd_xpkMode; */
  125.       }
  126.     
  127.       /* check for password flag */
  128.       if(h.pd_xpkPacker && !err && !(err = xadHookAccess(XADAC_READ, 40, dat, ai))
  129.       && !(err = xadHookAccess(XADAC_INPUTSEEK, -40, 0, ai)))
  130.       {
  131.         if(dat[9] & (1<<25))
  132.           ai->xai_Flags |= XADAIF_CRYPTED;
  133.       }
  134.  
  135.       if(h.pd_KnownFileSys)
  136.       {
  137.         blksiz = h.pd_BlockNum;
  138.         if(h.pd_xpkPacker)
  139.         {
  140.           j = ai->xai_InPos;
  141.           if(!(err = PKDdecrBuf(&buf, &i, ai, xadMasterBase, h.pd_Header[3] == 0x11)))
  142.             err = xadHookAccess(XADAC_INPUTSEEK, j-ai->xai_InPos, 0, ai);
  143.         }
  144.         else
  145.         {
  146.           if(!(buf = (STRPTR) xadAllocVec((i = blksiz>>3), MEMF_ANY)))
  147.             err = XADERR_NOMEMORY;
  148.           else
  149.             err = xadHookAccess(XADAC_READ, i, buf, ai);
  150.         }
  151.       }
  152.     
  153.       if(!err)
  154.       {
  155.         if((xdi = (struct xadDiskInfo *) xadAllocObject(XADOBJ_DISKINFO,
  156.         blksiz ? XAD_OBJBLOCKENTRIES : TAG_DONE, blksiz, TAG_DONE)))
  157.         {
  158.           if(ai->xai_Flags & XADAIF_CRYPTED)
  159.             xdi->xdi_Flags |= XADDIF_CRYPTED;
  160.           xdi->xdi_Flags |= XADDIF_NOCYLINDERS|XADDIF_NOLOWCYL|
  161.                         XADDIF_NOHIGHCYL|XADDIF_NOHEADS|XADDIF_NOCYLSECTORS;
  162.           xdi->xdi_TotalSectors = h.pd_BlockNum;
  163.           xdi->xdi_SectorSize = h.pd_BlockSize;
  164.           xdi->xdi_TrackSectors = h.pd_TrackLength / h.pd_BlockSize;
  165.           xdi->xdi_EntryNumber = 1;
  166.           i = 0;
  167.           if(h.pd_xpkPacker)
  168.             i |= PKD_XPKPACKED;
  169.           if(h.pd_Header[3] == 0x11)
  170.             i |= PKD_OLDMODE;
  171.           xdi->xdi_PrivateInfo = (APTR) i;
  172.           ai->xai_DiskInfo = xdi;
  173.  
  174.       /* does nothing if blksiz == 0 */
  175.       for(i = 0; i < blksiz; ++i)
  176.           {
  177.             if(i < h.pd_Reserved || (buf[i/8] & ((1 << (7-(i%8))))))
  178.               xdi->xdi_BlockInfo[i] |= XADBIF_CLEARED;
  179.           }
  180.         }
  181.         else
  182.           err = XADERR_NOMEMORY;
  183.       }
  184.       if(buf)
  185.         xadFreeObjectA(buf, 0);
  186.     }
  187.   }
  188.  
  189.   return err;
  190. }
  191.  
  192. ASM(LONG) PackDev_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  193. REG(a6, struct xadMasterBase *xadMasterBase))
  194. {
  195.   ULONG p, i, j, trsec, numsecs = 0;
  196.   LONG err = 0, secsize;
  197.   struct xadDiskInfo *di;
  198.   STRPTR temp;
  199.   
  200.   p = ai->xai_InPos;
  201.   di = ai->xai_CurDisk;
  202.   secsize = di->xdi_SectorSize;
  203.   trsec = di->xdi_TrackSectors;
  204.  
  205.   if(!(temp = xadAllocVec(di->xdi_SectorSize*di->xdi_TrackSectors, MEMF_ANY)))
  206.     return XADERR_NOMEMORY;
  207.  
  208.   if(!(((ULONG) di->xdi_PrivateInfo) & PKD_XPKPACKED))
  209.   {
  210.     numsecs = 0;
  211.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  212.     {
  213.       j = (i % trsec)*secsize;
  214.     
  215.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  216.         memset(temp+j, 0, secsize);
  217.       else
  218.       {
  219.         err = xadHookAccess(XADAC_READ, secsize, temp+j, ai);
  220.         ++numsecs;
  221.       }
  222.       /* skip the sectorlabel and write data */
  223.       if((i % trsec) == (trsec-1) && !err)
  224.       {
  225.         if(!numsecs || !(err = xadHookAccess(XADAC_INPUTSEEK, TD_LABELSIZE*numsecs, 0, ai)))
  226.           err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  227.         numsecs = 0;
  228.       }
  229.     }
  230.   }
  231.   else
  232.   {
  233.     ULONG size;
  234.     LONG pos = 0, ressize;
  235.     STRPTR buf = 0;
  236.  
  237.     err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  238.     (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE));
  239.  
  240.     if(di->xdi_BlockInfo)
  241.       pos += di->xdi_TotalSectors>>3;
  242.  
  243.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  244.     {
  245.       j = (i % trsec)*secsize;
  246.       
  247.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  248.         memset(temp+j, 0, secsize);
  249.       else
  250.       {
  251.         ++numsecs;
  252.         if((ressize = size-pos) >= secsize)
  253.         {
  254.           xadCopyMem(buf+pos, temp+j, secsize);
  255.           pos += secsize;
  256.         }
  257.         else
  258.         {
  259.           if(ressize > 0)
  260.           {
  261.             xadCopyMem(buf+pos, temp+j, ressize);
  262.             pos += ressize;
  263.           }
  264.           else if(ressize < 0)
  265.             ressize = 0;
  266.           xadFreeObjectA(buf, 0);
  267.           buf = 0;
  268.           pos -= size;
  269.           if(!(err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  270.           (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE))))
  271.           {
  272.             xadCopyMem(buf+pos, temp+j+ressize, secsize-ressize);
  273.             pos += secsize-ressize;
  274.           }
  275.         }
  276.       }
  277.       /* skip the sectorlabel and write data */
  278.       if((i % trsec) == (trsec-1) && !err)
  279.       {
  280.         pos += TD_LABELSIZE*numsecs;
  281.         err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  282.         numsecs = 0;
  283.       }
  284.     }
  285.     if(buf)
  286.       xadFreeObjectA(buf, 0);
  287.   }
  288.  
  289.   if(p != ai->xai_InPos)
  290.     xadHookAccess(XADAC_INPUTSEEK, p-ai->xai_InPos, 0, ai);
  291.  
  292.   xadFreeObjectA(temp, 0);
  293.  
  294.   return err;
  295. }
  296.  
  297. struct xadClient PackDev_Client = {
  298. NEXTCLIENT, XADCLIENT_VERSION, 2, PACKDEV_VERSION, PACKDEV_REVISION,
  299. 4, XADCF_DISKARCHIVER|XADCF_FREEDISKINFO, XADCID_PACKDEV, "PackDev",
  300. (BOOL (*)()) PackDev_RecogData, (LONG (*)()) PackDev_GetInfo,
  301. (LONG (*)()) PackDev_UnArchive, 0};
  302.  
  303. #endif /* XADASTER_PACKDEV_C */
  304.