home *** CD-ROM | disk | FTP | other *** search
- #ifndef XPKMASTER_OPEN_C
- #define XPKMASTER_OPEN_C
-
- /* Routinesheader
-
- Name: open.c
- Main: xpkmaster
- Versionstring: $VER: open.c 1.19 (30.10.1998)
- Author: SDI
- Distribution: Freeware
- Description: Opening and initialisation routines for XPK files
-
- 1.0 06.10.96 : first real version
- 1.1 28.10.96 : reincluded A4 support
- 1.2 03.03.97 : added Prefs, corrected length recognition
- 1.3 07.03.97 : fixed prefs handling, new features
- 1.4 09.03.97 : added DEBUG statement
- 1.5 28.03.97 : auto decrunch password
- 1.6 29.03.97 : fixed prefs stuff, moved getinlen into hooks
- 1.7 31.03.97 : changed the password stuff
- 1.8 19.12.97 : added xfdmaster.library support
- 1.9 22.12.97 : fixed auto password problem
- 1.10 27.12.97 : fixed GetPassword error
- 1.11 09.01.98 : better key handling
- 1.12 21.01.98 : added password verification for packing
- 1.13 24.01.98 : fixed xfdmaster support a bit
- 1.14 17.02.98 : fixe long file problem added in last version
- 1.15 21.02.98 : uses new style register definition
- 1.16 26.03.98 : some optimizations
- 1.17 26.08.98 : may skip reading insize for packing, when no inhook
- 1.18 13.09.98 : removed PP stuff
- 1.19 30.10.98 : some changes for seek support
- */
-
- #include <xpk/xpkprefs.h>
- #include <exec/memory.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/xpkmaster.h>
- #include <proto/xpksub.h>
- #include <proto/xfdmaster.h>
- #include "xpkmaster.h"
- #include "texts.h"
-
- static const struct XpkInfo DONTInfo = { 1,0,0,1,"DONT","Copy",
- 0, 0x55534552, XPKIF_PK_CHUNK|XPKIF_UP_CHUNK, DEFAULTCHUNKSIZE, 1,
- DEFAULTCHUNKSIZE,0,0,0,0,100,0,0,0,0,0,0,0,0};
- /* XpkMode is not initialized! Should not be used anywhere */
-
- static LONG xpkopenwrite(struct XpkBuffer **, struct TagItem *);
- static LONG GetPrefsPacker(struct XpkBuffer *);
- static LONG GetPassword(struct XpkBuffer *, struct TagItem *, ULONG);
- static struct XpkTypeData *BufRecog(ULONG, struct XpkBuffer *,
- struct XpkPrefsSemaphore *);
-
- XPK_ALLINONE ASM(LONG) xpkopen(REG(a0, struct XpkBuffer **xbufp),
- REG(a1, struct TagItem *tags), REG(d2, ULONG examine A4PROTO))
- {
- struct XpkBuffer *xbuf;
- struct XpkStreamHeader *globhdr;
- struct XpkFib *fib;
-
- #if defined(DEBUG) && defined(SUPPORT_A4)
- DebugRunTime("xpkopen: A4 = %ld", a4);
- #elif defined (DEBUG)
- DebugRunTime("xpkopen");
- #endif
-
- if(!(*xbufp = xbuf = initxbuf()))
- return parseerrortags(tags, XPKERR_NOMEM);
-
- #ifdef SUPPORT_A4
- xbuf->xb_regA4 = a4;
- #endif
-
- globhdr = &xbuf->xb_Headers.h_Glob;
- fib = &xbuf->xb_Fib;
-
- if(parsebuftags(xbuf, tags))
- goto Abort;
-
- if(xbuf->xb_Flags & XMF_PACKING) /* Call pack open function */
- return xpkopenwrite(xbufp, tags);
-
- if(!hookread(xbuf, XIO_READ, globhdr, 4)) /* Read first longword */
- {
- if(xbuf->xb_Result != XPKERR_TRUNCATED)
- goto Abort;
- /* else handle now as uncompressed file */
- }
-
- /***************************** Standard XPK file **********************/
- if(globhdr->xsh_Pack == XPK_COOKIE)
- {
- UWORD exthlen = 0; /* size of extended header if present */
- struct Library * XpkSubBase;
-
- xbuf->xb_Format = XPKMODE_UPSTD;
-
- /* Read rest of the global header */
- if(!hookread(xbuf, XIO_READ, (STRPTR) globhdr + 4, sizeof(struct XpkStreamHeader) - 4))
- goto Abort;
-
- if(hchecksum((STRPTR) globhdr, sizeof(struct XpkStreamHeader)))
- {
- xbuf->xb_Result = XPKERR_CHECKSUM;
- goto Abort;
- }
-
- if(globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS)
- xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrLong);
- else
- xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrWord);
-
- if(globhdr->xsh_Flags & XPKSTREAMF_EXTHEADER)
- {
- if(!hookread(xbuf, XIO_READ, &exthlen, sizeof(UWORD)))
- goto Abort;
- if(!hookread(xbuf, XIO_READ, NULL, exthlen))
- goto Abort;
- exthlen += sizeof(UWORD); /* for unwinding while XpkExamine */
- }
-
- if(!hookread(xbuf, XIO_READ, &xbuf->xb_Headers.h_Loc,
- xbuf->xb_Headers.h_LocSize)) /* first lochdr */
- goto Abort;
-
- fib->xf_CCur = sizeof(struct XpkStreamHeader);
- if(updatefib(xbuf))
- goto Abort;
- xbuf->xb_InLen = fib->xf_CLen;
-
- if(!(XpkSubBase = opensub(xbuf, globhdr->xsh_Type)))
- goto Abort;
-
- if(globhdr->xsh_SubVrs > xbuf->xb_SubInfo->xi_LibVersion)
- {
- xbuf->xb_Result = XPKERR_OLDSUBLIB;
- goto Abort;
- }
-
- xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_UnpackMsg ?
- xbuf->xb_SubInfo->xi_UnpackMsg : strings[TXT_UNPACKING_UPPER];
- xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
- xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_UnpackedMsg ?
- xbuf->xb_SubInfo->xi_UnpackedMsg : strings[TXT_UNPACKED];
-
- if(globhdr->xsh_Flags & XPKSTREAMF_PASSWORD)
- fib->xf_Flags |= XPKFLAGS_PASSWORD;
-
- if(examine && !hookread(xbuf, XIO_SEEK, 0,
- -(sizeof(struct XpkStreamHeader) + xbuf->xb_Headers.h_LocSize+exthlen)))
- goto Abort;
-
- goto Exit;
- }
-
- if(!hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_RMsg.xmm_Size))
- goto Abort; /* redo last read bytes */
-
- if(xbuf->xb_InLen == 0xFFFFFFFF)
- {
- if(!hookread(xbuf, XIO_TOTSIZE, 0, 0)) /* get input length */
- goto Abort;
- else if(xbuf->xb_RMsg.xmm_Size)
- xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
- }
-
- fib->xf_CLen = xbuf->xb_InLen;
-
- /**************************** xfdmaster file **************************/
- if(xbuf->xb_Flags & XMF_XFD &&
- (xbuf->xb_SubBase = OpenLibrary("xfdmaster.library", 38)))
- {
- struct xfdMasterBase *xfdMasterBase = (struct xfdMasterBase *) xbuf->xb_SubBase;
- struct xfdBufferInfo *xbi;
-
- if(!(xbi = xbuf->xb_xfd = (struct xfdBufferInfo *) xfdAllocObject(XFDOBJ_BUFFERINFO)))
- goto Abort;
- if(!(xbi->xfdbi_SourceBuffer = hookread(xbuf, XIO_READ, 0, xbuf->xb_InLen)))
- goto Abort;
- xbi->xfdbi_SourceBufLen = xbuf->xb_InLen;
- xbi->xfdbi_Flags = XFDFF_RECOGEXTERN|XFDFF_RECOGTARGETLEN|XFDFF_RECOGUSERTARGET;
-
- if(xfdRecogBuffer(xbi) && (xbi->xfdbi_PackerFlags & XFDPFF_DATA) &&
- (LONG) xbi->xfdbi_FinalTargetLen != -1)
- {
- xbuf->xb_Format = XPKMODE_UPXFD;
- if(xbi->xfdbi_PackerFlags & XFDPFF_PASSWORD)
- xbuf->xb_Fib.xf_Flags |= XPKFLAGS_PASSWORD;
- if(xbi->xfdbi_PackerFlags & XFDPFF_KEY16)
- xbuf->xb_Fib.xf_Flags |= XPKFLAGS_KEY16;
- if(xbi->xfdbi_PackerFlags & XFDPFF_KEY32)
- xbuf->xb_Fib.xf_Flags |= XPKFLAGS_KEY32;
- fib->xf_Type = XPKTYPE_PACKED;
- fib->xf_ULen = xbi->xfdbi_FinalTargetLen;
- fib->xf_NLen = xbi->xfdbi_MinTargetLen;
- fib->xf_ID = XFD_COOKIE;
- percentages(fib);
- xbuf->xb_Prog.xp_Activity = strings[TXT_UNPACKING_UPPER];
- xbuf->xb_Prog.xp_PackerName = "XFDMaster";
- xbuf->xb_LastMsg = strings[TXT_UNPACKED];
-
- if(examine && !hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_InLen))
- goto Abort; /* return to start */
-
- #ifdef DEBUG
- DebugRunTime("xpkopen: XFD, InLen %ld, OutLen %ld, NLen %ld",
- xbuf->xb_InLen, fib->xf_ULen, fib->xf_NLen);
- #endif
- goto Exit;
- } /* xfdRecogBuffer */
-
- if(!hookread(xbuf, XIO_SEEK, 0, -xbuf->xb_InLen))
- goto Abort; /* return to start */
- }
-
- /*************************** Uncompressed file ************************/
- if(examine || xbuf->xb_Flags & XMF_PASSTHRU) /* Unpacked */
- {
- xbuf->xb_Format = XPKMODE_UPUP;
-
- fib->xf_Type = XPKTYPE_UNPACKED;
- fib->xf_ULen = xbuf->xb_InLen;
- fib->xf_NLen = Min(DEFAULTCHUNKSIZE, xbuf->xb_InLen) + XPK_MARGIN;
- fib->xf_ID = ROW_OF_MINUS;
-
- xbuf->xb_Prog.xp_Activity = strings[TXT_READING];
- xbuf->xb_Prog.xp_PackerName = "Master";
- xbuf->xb_LastMsg = strings[TXT_READ];
-
- xbuf->xb_Result = XPKERR_OK; /* if != 0 it was XPKERR_TRUNCATED */
-
- goto Exit;
- }
-
- xbuf->xb_Result = XPKERR_NOTPACKED; /* Can't unpack, can't passthru */
-
- Abort:
- *xbufp = 0;
- return XpkClose((struct XpkFib *) xbuf);
-
- Exit:
- if(!examine && (
- ((fib->xf_Flags & XPKFLAGS_PASSWORD) && !xbuf->xb_Password) ||
- ((fib->xf_Flags & XPKFLAGS_KEY16) && !(xbuf->xb_Flags & XMF_KEY16)) ||
- ((fib->xf_Flags & XPKFLAGS_KEY32) && !(xbuf->xb_Flags & XMF_KEY32)))
- && (xbuf->xb_Result = GetPassword(xbuf, tags, FALSE)))
- goto Abort;
-
- return XPKERR_OK;
- }
-
- /***************************** Open for packing *************************/
- static LONG xpkopenwrite(struct XpkBuffer **xbufp, struct TagItem *tags)
- {
- struct XpkBuffer *xbuf = *xbufp;
- struct XpkStreamHeader *globhdr = &xbuf->xb_Headers.h_Glob;
- struct Library *XpkSubBase;
- LONG res;
-
- xbuf->xb_Format = XPKMODE_PKSTD;
-
- if(xbuf->xb_InLen == 0xFFFFFFFF && xbuf->xb_RHook)
- {
- if(!hookread(xbuf, XIO_TOTSIZE, 0, 0)) /* get input length */
- return xbuf->xb_Result;
- else if(xbuf->xb_RMsg.xmm_Size)
- xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
- }
-
- xbuf->xb_Fib.xf_ULen = xbuf->xb_InLen;
-
- if(!(XpkSubBase = xbuf->xb_SubBase) && /* Do we know the sublib? */
- (xbuf->xb_Result = GetPrefsPacker(xbuf)))
- goto Abort; /* no sublib and no prefs packer finder */
-
- if(xbuf->xb_Password && !(xbuf->xb_SubInfo->xi_Flags & XPKIF_ENCRYPTION))
- {
- xbuf->xb_Result = XPKERR_NOCRYPT;
- goto Abort;
- }
-
- if(!xbuf->xb_Password && (xbuf->xb_SubInfo->xi_Flags & XPKIF_NEEDPASSWD))
- { /* automatic password requester */
- if((xbuf->xb_Result = GetPassword(xbuf, tags, TRUE)))
- goto Abort;
- }
-
- if(!(xbuf->xb_Flags & XMF_LOSSYOK) &&
- xbuf->xb_SubInfo->xi_Flags & XPKIF_LOSSY)
- {
- xbuf->xb_Result = XPKERR_LOSSY;
- goto Abort;
- }
-
- if(xbuf->xb_PackingMode > 100) /* Is packing mode valid? */
- xbuf->xb_PackingMode = 100; /* Use max */
-
- if(xbuf->xb_InLen != 0xFFFFFFFF)
- {
- if(!hookwrite(xbuf, XIO_TOTSIZE, 0, ROUNDLONG
- (xbuf->xb_InLen + (xbuf->xb_InLen >> 5)) + (XPK_MARGIN<<1)))
- goto Abort;
- }
-
- /************************* Find the chunk size ************************/
- if((xbuf->xb_ChunkSize == 0) &&
- ((xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_DefPkInChunk) == 0))
- xbuf->xb_ChunkSize = DEFAULTCHUNKSIZE;
- if(xbuf->xb_ChunkSize < xbuf->xb_SubInfo->xi_MinPkInChunk)
- xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MinPkInChunk;
- if((xbuf->xb_SubInfo->xi_MaxPkInChunk) &&
- (xbuf->xb_ChunkSize > xbuf->xb_SubInfo->xi_MaxPkInChunk))
- xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MaxPkInChunk;
-
- /************************ Prepare global header ***********************/
- globhdr->xsh_Pack = 0; /* Initialize the global header */
- globhdr->xsh_Type = xbuf->xb_SubID;
-
- if(xbuf->xb_ChunkSize > 65000) /* (0xFFFF-XPK_MARGIN) and some bytes security */
- globhdr->xsh_Flags |= XPKSTREAMF_LONGHEADERS;
- if(xbuf->xb_Password)
- globhdr->xsh_Flags |= XPKSTREAMF_PASSWORD;
-
- xbuf->xb_Headers.h_LocSize = globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS
- ? sizeof (struct XpkChunkHdrLong)
- : sizeof (struct XpkChunkHdrWord);
-
- memset(globhdr->xsh_Initial, 0xff, 16); /* Read first 16 bytes */
-
- xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_PackMsg ?
- xbuf->xb_SubInfo->xi_PackMsg : strings[TXT_PACKING_UPPER];
- xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
- xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_PackedMsg ?
- xbuf->xb_SubInfo->xi_PackedMsg : strings[TXT_PACKED];
-
- Abort:
- xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur,
- xbuf->xb_ChunkSize);
-
- if((res = xbuf->xb_Result))
- res = XpkClose((struct XpkFib *) xbuf);
-
- return res;
- }
-
- typedef ASM(struct XpkTypeData *) (*RecogFunc) (REG(a0, STRPTR),
- REG(a1, STRPTR), REG(d0, ULONG), REG(d1, ULONG),
- REG(a2, struct TagItem *));
-
- static LONG GetPrefsPacker(struct XpkBuffer *xbuf)
- {
- LONG ret = XPKERR_UNKNOWN;
- struct XpkPrefsSemaphore *sem;
- ULONG bufsize;
- struct XpkTypeData *td = 0;
-
- if((xbuf->xb_Flags & XMF_NOPREFS) || !xbuf->xb_RHook)
- return XPKERR_BADPARAMS;
- if(!(sem = GetPrefsSem()))
- return XPKERR_NOFUNC;
-
- bufsize = Min(xbuf->xb_InLen, sem->xps_RecogSize);
-
- if(sem->xps_RecogFunc && (td = BufRecog(bufsize, xbuf, sem)) ==
- (struct XpkTypeData *) 0xFFFFFFFF)
- td = BufRecog(xbuf->xb_InLen, xbuf, sem);
-
- if(!td || td == (struct XpkTypeData *) 0xFFFFFFFF)
- td = sem->xps_MainPrefs ? sem->xps_MainPrefs->xmp_DefaultType : 0;
-
- if(td)
- {
- if(td->xtd_Flags & XTD_NoPack)
- {
- xbuf->xb_Flags |= XMF_NOPACK;
- xbuf->xb_SubInfo = (struct XpkInfo *) &DONTInfo;
- ret = XPKERR_OK;
- }
- else if(!(td->xtd_Flags & XTD_ReturnError))
- {
- struct Library *XpkSubBase;
- struct XpkInfo *subinfo;
-
- if((XpkSubBase = opensub(xbuf, td->xtd_StdID)))
- {
- ret = XPKERR_OK;
- subinfo = XpksPackerInfo();
-
- xbuf->xb_ChunkSize = td->xtd_ChunkSize;
- xbuf->xb_PackingMode = ( td->xtd_Mode ? td->xtd_Mode :
- subinfo->xi_DefMode);
- // if(!(xbuf->xb_Password) && td->xtd_Password &&
- // (xbuf->xb_PasswordSize = strlen(td->xtd_Password)))
- // {
- // /* we need a buffer including end byte! --> ++size */
- // if(!(xbuf->xb_Password = (STRPTR)
- // AllocMem(++xbuf->xb_PasswordSize, MEMF_PUBLIC)))
- // ret = XPKERR_NOMEM;
- // else
- // {
- // xbuf->Flags |= XMF_OWNPASSWORD;
- // CopyMem(td->xtd_Password, xbuf->xb_Password, xbuf->xb_PasswordSize);
- // }
- // }
- }
- }
- else
- ret = XPKERR_NOMETHOD;
- }
-
- if(td->xtd_Memory && td->xtd_MemorySize)
- FreeMem(td->xtd_Memory, td->xtd_MemorySize);
-
- ReleaseSemaphore((struct SignalSemaphore *) sem);
- return ret;
- }
-
- static LONG GetPassword(struct XpkBuffer *xbuf, struct TagItem *tags,
- ULONG verify)
- {
- if(xbuf->xb_Flags & XMF_AUTOPASSWD)
- {
- if(xbuf->xb_Fib.xf_Flags & XPKFLAGS_KEY32)
- {
- xbuf->xb_Result = XpkPassRequestTags(XPK_Key32BitPtr,
- &xbuf->xb_PassKey32, TAG_MORE, tags, TAG_DONE);
- xbuf->xb_Flags |= XMF_KEY32;
- }
- else if(xbuf->xb_Fib.xf_Flags & XPKFLAGS_KEY16)
- {
- xbuf->xb_Result = XpkPassRequestTags(XPK_Key16BitPtr,
- &xbuf->xb_PassKey16, TAG_MORE, tags, TAG_DONE);
- xbuf->xb_Flags |= XMF_KEY16;
- }
- else
- {
- if(!(xbuf->xb_Password = (STRPTR) AllocMem(AUTO_PASS_SIZE, MEMF_PUBLIC)))
- return XPKERR_NOMEM;
- xbuf->xb_PasswordSize = AUTO_PASS_SIZE;
- xbuf->xb_Flags |= XMF_OWNPASSWORD; /* must be freed later */
-
- xbuf->xb_Result = XpkPassRequestTags(XPK_PasswordBuf,
- xbuf->xb_Password, XPK_PassBufSize, xbuf->xb_PasswordSize,
- XPK_PassVerify, verify, TAG_MORE, tags, TAG_DONE);
- }
-
- return xbuf->xb_Result;
- }
- return XPKERR_NEEDPASSWD;
- }
-
- static struct XpkTypeData *BufRecog(ULONG bufsize, struct XpkBuffer *xbuf,
- struct XpkPrefsSemaphore *sem)
- {
- STRPTR bufptr;
- struct XpkTypeData *ret = 0;
- struct TagItem tag[] = {
- { XPK_FileName, 0},
- { XPK_PackMode, 0},
- { TAG_DONE, 0}};
-
- tag[0].ti_Data = (ULONG) xbuf->xb_Prog.xp_FileName;
- tag[1].ti_Data = xbuf->xb_PackingMode;
-
- if((bufptr = (STRPTR) hookread(xbuf, XIO_READ, 0, bufsize)))
- {
- ret = (((RecogFunc) sem->xps_RecogFunc) (bufptr,
- xbuf->xb_RMsg.xmm_FileName, bufsize, xbuf->xb_InLen, tag));
- hookread(xbuf, XIO_SEEK, 0, -bufsize);
- }
- return ret;
- }
-
- #endif /* XPKMASTER_OPEN_C */
-