#ifndef XADMASTER_XPKSTUFF_C
#define XADMASTER_XPKSTUFF_C

/* Programmheader

	Name:		xpkstuff.c
	Main:		xadmaster
	Versionstring:	$VER: xpkstuff.c 1.1 (10.08.1998)
	Author:		SDI
	Distribution:	Freeware
	Description:	xpk decrunch handling

 1.0   14.06.98 : first version
 1.1   10.08.98 : completed xpkDecrunch
*/

#include <proto/xpkmaster.h>
#include <proto/xadmaster.h>
#include <proto/exec.h>
#include <exec/memory.h>

LONG GetXpkError(LONG err);

/* reads XPKF file from current input stream and stores a pointer to
decrunched file in *str and the size in *size */
LONG xpkDecrunch(STRPTR *str, ULONG *size, struct xadArchiveInfo *ai,
struct xadMasterBase *xadMasterBase)
{
  struct Library *XpkBase;
  struct ExecBase * SysBase = xadMasterBase->xmb_SysBase;
  ULONG buf[2];
  LONG err;
  ULONG *mem;
  
  if((XpkBase = OpenLibrary("xpkmaster.library", 4)))
  {
    if(!(err = xadHookAccess(XADAC_READ, 8, buf, ai)))
    {
      if((mem = AllocMem(buf[1]+8, MEMF_PUBLIC)))
      {
        if(!(err = xadHookAccess(XADAC_READ, buf[1], mem+2, ai)))
        {
          struct XpkFib xfib;

          mem[0] = buf[0];
          mem[1] = buf[1];

          if(!XpkExamineTags(&xfib, XPK_InBuf, mem,
          XPK_InLen, buf[1]+8, TAG_DONE))
          {
            STRPTR mem2;

	    if((mem2 = (STRPTR) AllocVec(xfib.xf_ULen+XPK_MARGIN,
	    MEMF_PUBLIC|MEMF_CLEAR)))
	    {
	      *str = mem2;
	      *size = xfib.xf_ULen;

              if((err = GetXpkError(XpkUnpackTags(XPK_InBuf, mem,
              XPK_InLen, buf[1]+8, XPK_OutBuf, mem2, XPK_OutBufLen,
              *size + XPK_MARGIN, ai->xai_Password ? XPK_Password :
              TAG_IGNORE, ai->xai_Password, XPK_UseXfdMaster, 0,
              XPK_PassRequest, FALSE, TAG_DONE))))
              {
                FreeVec(mem2); *str = 0; *size = 0;
              }
            }
          }
          else
            err = XADERR_ILLEGALDATA;
        }  
        FreeMem(mem, buf[1]+8);
      } /* AllocMem */
      else
        err = XADERR_NOMEMORY;
    } /* Hook Read */
    CloseLibrary(XpkBase);
  } /* OpenLibrary */
  else
    err = XADERR_RESOURCE;

  return err;
}

LONG GetXpkError(LONG err)
{
  LONG ret;

  switch(err)
  {
    case XPKERR_OK:		ret = XADERR_OK; break;
    case XPKERR_IOERRIN:	ret = XADERR_INPUT; break;
    case XPKERR_IOERROUT:	ret = XADERR_OUTPUT; break;
    case XPKERR_CORRUPTPKD:
    case XPKERR_TRUNCATED:	ret = XADERR_ILLEGALDATA; break;
    case XPKERR_NOMEM:		ret = XADERR_NOMEMORY; break;
    case XPKERR_WRONGCPU:
    case XPKERR_MISSINGLIB:
    case XPKERR_VERSION:
    case XPKERR_OLDMASTLIB:
    case XPKERR_OLDSUBLIB:
    case XPKERR_NOHARDWARE:
    case XPKERR_BADHARDWARE:	ret = XADERR_RESOURCE; break;
    case XPKERR_NEEDPASSWD:
    case XPKERR_WRONGPW:	ret = XADERR_PASSWORD; break;
    default:			ret = XADERR_DECRUNCH; break;
  };
  return ret;
}

#endif /* XADASTER_XPKDECRUNCH_C */
