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