home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ANews 1
/
AnewsCD01.iso
/
Indispensables
/
Compression
/
xad
/
Developer
/
Sources
/
clients
/
PackDev.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-08-09
|
9KB
|
304 lines
#ifndef XADMASTER_PACKDEV_C
#define XADMASTER_PACKDEV_C
/* Programmheader
Name: PackDev.c
Main: xadmaster
Versionstring: $VER: PackDev.c 1.3 (29.06.1999)
Author: SDI
Distribution: Freeware
Description: PackDev disk archiver client
1.0 13.06.98 : first version
1.1 13.02.99 : started again with that client
1.2 20.06.99 : removed exec.library calls
1.3 29.06.99 : now uses master free stuff
*/
/* For now SectorLabel information is ignored, as current
xadmaster.library does not support SectorLabels. */
#include <proto/xadmaster.h>
#include <devices/trackdisk.h>
#include "SDI_compiler.h"
#define SDI_TO_ANSI
#include "SDI_ASM_STD_protos.h"
#include "xpkstuff.c"
#ifndef XADMASTERFILE
#define PackDev_Client FirstClient
#define NEXTCLIENT 0
UBYTE version[] = "$VER: PackDev 1.3 (29.06.1999)";
#endif
#define PACKDEV_VERSION 1
#define PACKDEV_REVISION 3
struct PackDevHead {
UBYTE pd_Header[4]; /* equals 'PKD\x13' */
ULONG pd_BlockNum; /* Number of blocks */
ULONG pd_BlockSize; /* size of one block */
ULONG pd_Reserved; /* Reserved blocks */
ULONG pd_TrackLength; /* Length of one track*/
ULONG pd_xpkBufferSize; /* in byte */
ULONG pd_xpkPacker; /* XPK packer type */
ULONG pad1; /* These are fields containing the XPK packer name */
ULONG pad2; /* Don't know, why the author used 24bytes instead */
ULONG pad3; /* of the required 4. */
ULONG pad4; /* The fields are ignored by that client */
ULONG pad5;
UWORD pd_xpkMode; /* XPK mode Number 0..100 */
UWORD pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
};
struct PackDevHeadOld {
UBYTE pd_Header[4]; /* equals 'PKD\x11' */
ULONG pd_BlockNum; /* Number of blocks */
ULONG pd_BlockSize; /* size of one block */
ULONG pd_Reserved; /* Reserved blocks */
ULONG pd_TrackLength; /* Length of one track*/
ULONG pd_xpkBufferSize; /* in byte */
ULONG pd_xpkPacker; /* XPK packer type */
UWORD pd_xpkMode; /* XPK mode Number 0..100 */
UWORD pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
};
/* Every block has following structure:
ULONG size
ULONG data[...]
ULONG checksum
Where data are the blocks and additionally the SectorLabels (16 Byte).
NOTE: xadmaster does not support to extract the label data in current version!
Checksum is missing in PackDev11 Version.
*/
#define PKD_XPKPACKED (1<<0)
#define PKD_OLDMODE (1<<1)
ASM(BOOL) PackDev_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
REG(a6, struct xadMasterBase *xadMasterBase))
{
if(((ULONG *)data)[0] == 0x504B4413 || ((ULONG *)data)[0] == 0x504B4411)
return 1;
else
return 0;
}
LONG PKDdecrBuf(STRPTR *buf, ULONG *i, struct xadArchiveInfo *ai,
struct xadMasterBase *xadMasterBase, ULONG oldmode)
{
LONG err, size;
if(!(err = xadHookAccess(XADAC_READ, 4, &size, ai)))
{
if(!(err = xpkDecrunch(buf, i, ai, xadMasterBase)))
{
if(!oldmode)
err = xadHookAccess(XADAC_READ, 4, &size, ai);
}
}
return err;
}
/* maybe there are some errors in that code, not tested yet */
ASM(LONG) PackDev_GetInfo(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
{
struct PackDevHead h;
LONG err;
if(!(err = xadHookAccess(XADAC_READ, sizeof(struct PackDevHeadOld), &h, ai)))
{
if(h.pd_Header[3] == 0x11 || !(err = xadHookAccess(XADAC_READ,
sizeof(struct PackDevHead)-sizeof(struct PackDevHeadOld), ((STRPTR) &h) +
sizeof(struct PackDevHeadOld), ai)))
{
struct xadDiskInfo *xdi;
ULONG blksiz = 0, i, j, dat[10];
STRPTR buf = 0;
if(h.pd_Header[3] == 0x11)
{
h.pd_KnownFileSys = ((struct PackDevHeadOld *) &h)->pd_KnownFileSys;
/* h.pd_xpkMode = ((struct PackDevHeadOld *) &h)->pd_xpkMode; */
}
/* check for password flag */
if(h.pd_xpkPacker && !err && !(err = xadHookAccess(XADAC_READ, 40, dat, ai))
&& !(err = xadHookAccess(XADAC_INPUTSEEK, -40, 0, ai)))
{
if(dat[9] & (1<<25))
ai->xai_Flags |= XADAIF_CRYPTED;
}
if(h.pd_KnownFileSys)
{
blksiz = h.pd_BlockNum;
if(h.pd_xpkPacker)
{
j = ai->xai_InPos;
if(!(err = PKDdecrBuf(&buf, &i, ai, xadMasterBase, h.pd_Header[3] == 0x11)))
err = xadHookAccess(XADAC_INPUTSEEK, j-ai->xai_InPos, 0, ai);
}
else
{
if(!(buf = (STRPTR) xadAllocVec((i = blksiz>>3), MEMF_ANY)))
err = XADERR_NOMEMORY;
else
err = xadHookAccess(XADAC_READ, i, buf, ai);
}
}
if(!err)
{
if((xdi = (struct xadDiskInfo *) xadAllocObject(XADOBJ_DISKINFO,
blksiz ? XAD_OBJBLOCKENTRIES : TAG_DONE, blksiz, TAG_DONE)))
{
if(ai->xai_Flags & XADAIF_CRYPTED)
xdi->xdi_Flags |= XADDIF_CRYPTED;
xdi->xdi_Flags |= XADDIF_NOCYLINDERS|XADDIF_NOLOWCYL|
XADDIF_NOHIGHCYL|XADDIF_NOHEADS|XADDIF_NOCYLSECTORS;
xdi->xdi_TotalSectors = h.pd_BlockNum;
xdi->xdi_SectorSize = h.pd_BlockSize;
xdi->xdi_TrackSectors = h.pd_TrackLength / h.pd_BlockSize;
xdi->xdi_EntryNumber = 1;
i = 0;
if(h.pd_xpkPacker)
i |= PKD_XPKPACKED;
if(h.pd_Header[3] == 0x11)
i |= PKD_OLDMODE;
xdi->xdi_PrivateInfo = (APTR) i;
ai->xai_DiskInfo = xdi;
/* does nothing if blksiz == 0 */
for(i = 0; i < blksiz; ++i)
{
if(i < h.pd_Reserved || (buf[i/8] & ((1 << (7-(i%8))))))
xdi->xdi_BlockInfo[i] |= XADBIF_CLEARED;
}
}
else
err = XADERR_NOMEMORY;
}
if(buf)
xadFreeObjectA(buf, 0);
}
}
return err;
}
ASM(LONG) PackDev_UnArchive(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
{
ULONG p, i, j, trsec, numsecs = 0;
LONG err = 0, secsize;
struct xadDiskInfo *di;
STRPTR temp;
p = ai->xai_InPos;
di = ai->xai_CurDisk;
secsize = di->xdi_SectorSize;
trsec = di->xdi_TrackSectors;
if(!(temp = xadAllocVec(di->xdi_SectorSize*di->xdi_TrackSectors, MEMF_ANY)))
return XADERR_NOMEMORY;
if(!(((ULONG) di->xdi_PrivateInfo) & PKD_XPKPACKED))
{
numsecs = 0;
for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
{
j = (i % trsec)*secsize;
if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
memset(temp+j, 0, secsize);
else
{
err = xadHookAccess(XADAC_READ, secsize, temp+j, ai);
++numsecs;
}
/* skip the sectorlabel and write data */
if((i % trsec) == (trsec-1) && !err)
{
if(!numsecs || !(err = xadHookAccess(XADAC_INPUTSEEK, TD_LABELSIZE*numsecs, 0, ai)))
err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
numsecs = 0;
}
}
}
else
{
ULONG size;
LONG pos = 0, ressize;
STRPTR buf = 0;
err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
(((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE));
if(di->xdi_BlockInfo)
pos += di->xdi_TotalSectors>>3;
for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
{
j = (i % trsec)*secsize;
if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
memset(temp+j, 0, secsize);
else
{
++numsecs;
if((ressize = size-pos) >= secsize)
{
xadCopyMem(buf+pos, temp+j, secsize);
pos += secsize;
}
else
{
if(ressize > 0)
{
xadCopyMem(buf+pos, temp+j, ressize);
pos += ressize;
}
else if(ressize < 0)
ressize = 0;
xadFreeObjectA(buf, 0);
buf = 0;
pos -= size;
if(!(err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
(((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE))))
{
xadCopyMem(buf+pos, temp+j+ressize, secsize-ressize);
pos += secsize-ressize;
}
}
}
/* skip the sectorlabel and write data */
if((i % trsec) == (trsec-1) && !err)
{
pos += TD_LABELSIZE*numsecs;
err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
numsecs = 0;
}
}
if(buf)
xadFreeObjectA(buf, 0);
}
if(p != ai->xai_InPos)
xadHookAccess(XADAC_INPUTSEEK, p-ai->xai_InPos, 0, ai);
xadFreeObjectA(temp, 0);
return err;
}
struct xadClient PackDev_Client = {
NEXTCLIENT, XADCLIENT_VERSION, 2, PACKDEV_VERSION, PACKDEV_REVISION,
4, XADCF_DISKARCHIVER|XADCF_FREEDISKINFO, XADCID_PACKDEV, "PackDev",
(BOOL (*)()) PackDev_RecogData, (LONG (*)()) PackDev_GetInfo,
(LONG (*)()) PackDev_UnArchive, 0};
#endif /* XADASTER_PACKDEV_C */