mirror of
https://github.com/MacPaw/XADMaster.git
synced 2025-08-29 03:23:48 +02:00
231 lines
7.4 KiB
C
231 lines
7.4 KiB
C
#ifndef XADMASTER_HOOK_STREAM_C
|
|
#define XADMASTER_HOOK_STREAM_C
|
|
|
|
/* $Id: hook_stream.c,v 1.6 2005/06/23 14:54:37 stoecker Exp $
|
|
XAD Stream IO hooks
|
|
|
|
XAD library system for archive handling
|
|
Copyright (C) 1998 and later by Dirk Stöcker <soft@dstoecker.de>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#ifdef AMIGA
|
|
#include <proto/xadmaster.h>
|
|
#include <proto/utility.h>
|
|
#endif
|
|
#include "include/functions.h"
|
|
#include "include/SDI_compiler.h"
|
|
|
|
/************************************************************************
|
|
* *
|
|
* In/OutHookStream private structure *
|
|
* *
|
|
************************************************************************/
|
|
|
|
struct StreamPrivate
|
|
{
|
|
struct xadArchiveInfo *ai;
|
|
struct TagItem ti[6];
|
|
/* XAD_USESKIPINFO, XAD_GETCRC16, XAD_GETCRC32, XAD_CRC16ID, XAD_CRC32ID, TAG_DONE */
|
|
};
|
|
|
|
/*************************** read-from-mem hook **************************/
|
|
|
|
|
|
FUNCHOOK(InHookStream)
|
|
{
|
|
xadERROR err = 0;
|
|
struct xadMasterBaseP *xadMasterBase;
|
|
struct StreamPrivate *sp;
|
|
|
|
xadMasterBase = ai->xaip_MasterBase;
|
|
sp = (struct StreamPrivate *) param->xhp_PrivatePtr;
|
|
|
|
switch(param->xhp_Command)
|
|
{
|
|
case XADHC_READ:
|
|
if(param->xhp_DataPos + param->xhp_BufferSize > ai->xaip_InSize)
|
|
err = XADERR_INPUT;
|
|
else if(param->xhp_BufferPtr)
|
|
{
|
|
err = xadHookTagAccessA(XADM_PRIV XADAC_READ, param->xhp_BufferSize,
|
|
param->xhp_BufferPtr, XADM_AI(sp->ai), sp->ti);
|
|
param->xhp_DataPos += param->xhp_BufferSize;
|
|
}
|
|
break;
|
|
case XADHC_SEEK:
|
|
if(((xadSignSize)param->xhp_DataPos + param->xhp_CommandData < 0)
|
|
|| (param->xhp_DataPos + param->xhp_CommandData > ai->xaip_InSize))
|
|
{
|
|
return XADERR_INPUT;
|
|
}
|
|
err = xadHookTagAccessA(XADM_PRIV XADAC_INPUTSEEK,
|
|
param->xhp_CommandData, 0, XADM_AI(sp->ai), sp->ti);
|
|
param->xhp_DataPos += param->xhp_CommandData;
|
|
break;
|
|
case XADHC_INIT:
|
|
#ifdef DEBUG
|
|
DebugOther("InHookStream: XADHC_INIT");
|
|
#endif
|
|
if((sp = xadAllocVec(XADM sizeof(struct StreamPrivate), XADMEMF_PUBLIC|XADMEMF_CLEAR)))
|
|
{
|
|
xadTAGPTR ti, ti2;
|
|
#ifdef AMIGA
|
|
struct UtilityBase *UtilityBase = xadMasterBase->xmb_UtilityBase;
|
|
#endif
|
|
xadINT32 i;
|
|
|
|
param->xhp_PrivatePtr = sp;
|
|
|
|
for(i = 0; i < 5; ++i)
|
|
sp->ti[i].ti_Tag = TAG_IGNORE;
|
|
sp->ti[5].ti_Tag = TAG_DONE;
|
|
|
|
ti = ti2 = ai->xaip_InArcInfo;
|
|
while((ti2 = NextTagItem(&ti)))
|
|
{
|
|
switch(ti2->ti_Tag)
|
|
{
|
|
case XAD_ARCHIVEINFO: sp->ai = (struct xadArchiveInfo *)(uintptr_t) ti2->ti_Data; break;
|
|
case XAD_USESKIPINFO: sp->ti[0].ti_Tag = ti2->ti_Tag; sp->ti[0].ti_Data = ti2->ti_Data; break;
|
|
case XAD_GETCRC32: sp->ti[1].ti_Tag = ti2->ti_Tag; sp->ti[1].ti_Data = ti2->ti_Data; break;
|
|
case XAD_GETCRC16: sp->ti[2].ti_Tag = ti2->ti_Tag; sp->ti[2].ti_Data = ti2->ti_Data; break;
|
|
case XAD_CRC32ID: sp->ti[3].ti_Tag = ti2->ti_Tag; sp->ti[3].ti_Data = ti2->ti_Data; break;
|
|
case XAD_CRC16ID: sp->ti[4].ti_Tag = ti2->ti_Tag; sp->ti[4].ti_Data = ti2->ti_Data; break;
|
|
}
|
|
}
|
|
|
|
for(i = 5; i >= 0 && sp->ti[i].ti_Tag == TAG_IGNORE; --i) /* reduce the number of TAG_IGNORE */
|
|
sp->ti[i].ti_Tag = TAG_DONE;
|
|
|
|
if(!sp->ai)
|
|
err = XADERR_BADPARAMS;
|
|
}
|
|
else
|
|
err = XADERR_NOMEMORY;
|
|
param->xhp_DataPos = 0;
|
|
break;
|
|
case XADHC_FREE:
|
|
if(param->xhp_PrivatePtr)
|
|
{
|
|
xadFreeObjectA(XADM param->xhp_PrivatePtr, 0);
|
|
param->xhp_PrivatePtr = 0;
|
|
}
|
|
break;
|
|
case XADHC_FULLSIZE:
|
|
param->xhp_CommandData = sp->ai->xai_InSize-sp->ai->xai_InPos;
|
|
if(sp->ti[0].ti_Data) /* use skipinfo */
|
|
{
|
|
param->xhp_CommandData += param->xhp_CommandData
|
|
- getskipsize(param->xhp_CommandData, (struct xadArchiveInfoP *) sp->ai);
|
|
}
|
|
#ifdef DEBUG
|
|
DebugOther("InHookStream: XADHC_FULLSIZE = %ld", param->xhp_CommandData);
|
|
#endif
|
|
break;
|
|
case XADHC_ABORT:
|
|
break;
|
|
default: return XADERR_NOTSUPPORTED;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
ENDFUNC
|
|
|
|
/*************************** write-to-mem hook **************************/
|
|
|
|
FUNCHOOK(OutHookStream)
|
|
{
|
|
xadERROR err = 0;
|
|
struct xadMasterBaseP *xadMasterBase;
|
|
struct StreamPrivate *sp;
|
|
|
|
xadMasterBase = ai->xaip_MasterBase;
|
|
sp = (struct StreamPrivate *) param->xhp_PrivatePtr;
|
|
|
|
switch(param->xhp_Command)
|
|
{
|
|
case XADHC_WRITE:
|
|
err = xadHookTagAccessA(XADM_PRIV XADAC_WRITE, param->xhp_BufferSize,
|
|
param->xhp_BufferPtr, XADM_AI(sp->ai), sp->ti);
|
|
param->xhp_DataPos += param->xhp_BufferSize;
|
|
break;
|
|
case XADHC_SEEK:
|
|
if(((xadSignSize)param->xhp_DataPos + param->xhp_CommandData < 0) || (param->xhp_DataPos + param->xhp_CommandData > ai->xaip_OutSize))
|
|
return XADERR_OUTPUT;
|
|
err = xadHookTagAccessA(XADM XADAC_OUTPUTSEEK, param->xhp_CommandData,
|
|
0, XADM_AI(sp->ai), sp->ti);
|
|
param->xhp_DataPos += param->xhp_CommandData;
|
|
break;
|
|
case XADHC_INIT:
|
|
#ifdef DEBUG
|
|
DebugOther("OutHookStream: XADHC_INIT");
|
|
#endif
|
|
if((sp = xadAllocVec(XADM sizeof(struct StreamPrivate), XADMEMF_PUBLIC|XADMEMF_CLEAR)))
|
|
{
|
|
xadTAGPTR ti, ti2;
|
|
#ifdef AMIGA
|
|
struct UtilityBase *UtilityBase = xadMasterBase->xmb_UtilityBase;
|
|
#endif
|
|
xadINT32 i;
|
|
|
|
param->xhp_PrivatePtr = sp;
|
|
|
|
for(i = 0; i < 5; ++i)
|
|
sp->ti[i].ti_Tag = TAG_IGNORE;
|
|
sp->ti[5].ti_Tag = TAG_DONE;
|
|
|
|
ti = ti2 = ai->xaip_InArcInfo;
|
|
while((ti2 = NextTagItem(&ti)))
|
|
{
|
|
switch(ti2->ti_Tag)
|
|
{
|
|
case XAD_ARCHIVEINFO: sp->ai = (struct xadArchiveInfo *)(uintptr_t) ti2->ti_Data; break;
|
|
case XAD_USESKIPINFO: sp->ti[0].ti_Tag = ti2->ti_Tag; sp->ti[0].ti_Data = ti2->ti_Data; break;
|
|
case XAD_GETCRC32: sp->ti[1].ti_Tag = ti2->ti_Tag; sp->ti[1].ti_Data = ti2->ti_Data; break;
|
|
case XAD_GETCRC16: sp->ti[2].ti_Tag = ti2->ti_Tag; sp->ti[2].ti_Data = ti2->ti_Data; break;
|
|
case XAD_CRC32ID: sp->ti[3].ti_Tag = ti2->ti_Tag; sp->ti[3].ti_Data = ti2->ti_Data; break;
|
|
case XAD_CRC16ID: sp->ti[4].ti_Tag = ti2->ti_Tag; sp->ti[4].ti_Data = ti2->ti_Data; break;
|
|
}
|
|
}
|
|
|
|
for(i = 5; i >= 0 && sp->ti[i].ti_Tag == TAG_IGNORE; --i) /* reduce the number of TAG_IGNORE */
|
|
sp->ti[i].ti_Tag = TAG_DONE;
|
|
|
|
if(!sp->ai)
|
|
err = XADERR_BADPARAMS;
|
|
}
|
|
else
|
|
err = XADERR_NOMEMORY;
|
|
param->xhp_DataPos = 0;
|
|
break;
|
|
case XADHC_FREE:
|
|
if(param->xhp_PrivatePtr)
|
|
{
|
|
xadFreeObjectA(XADM_PRIV param->xhp_PrivatePtr, 0);
|
|
param->xhp_PrivatePtr = 0;
|
|
}
|
|
break;
|
|
case XADHC_ABORT:
|
|
break;
|
|
default: return XADERR_NOTSUPPORTED;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
ENDFUNC
|
|
|
|
#endif /* XADMASTER_HOOK_STREAM_C */
|