home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * *
- * PowerPacker DATA file support function V1.1 *
- * ------------------------------------------- *
- * (Read Packer.doc for more information) *
- * *
- * error = PP_LoadData (file, col, typeofmem, buffer, length, pw) *
- * with: *
- * char *file; filename *
- * UBYTE col; color (see ppdata.h) *
- * ULONG typeofmem type of memory that will be allocated *
- * UBYTE **buffer pointer to pointer to buffer *
- * ULONG *length pointer to buffer length *
- * char *pw; pointer to password or NULL *
- * *
- * NOTE: - After loading you must free the allocated memory: *
- * DO NOT FORGET !!!!! *
- * FreeMem (buffer, length); *
- * - Errors are defined in ppdata.h *
- * - For encrypted data call first with pw = NULL, then *
- * if error is PP_CRYPTED you know file is crypted. *
- * Prompt the user for a password and call again with *
- * pw pointing to this password. If the password is *
- * incorrect error is PP_PASSERR, otherwise the file will *
- * be loaded and decrypted. *
- * *
- * Example: *
- * *
- * #include <ppdata.h> *
- * ... *
- * *
- * UBYTE *mymem = NULL; *
- * ULONG mylen = 0; *
- * *
- * err = PP_LoadData ("df0:myfile.pp", DECR_POINTER, *
- * MEMF_PUBLIC+MEMF_CHIP, &mymem, &mylen, NULL); *
- * if (err == PP_LOADOK) { *
- * DoSomething (mymem, mylen); *
- * FreeMem (mymem, mylen); *
- * } *
- * else switch (err) { *
- * case PP_CRYPTED: *
- * puts ("File is encrypted !"); *
- * break; *
- * case PP_READERR: *
- * puts ("Loading error !!!"); *
- * break; *
- * ... *
- * } *
- * *
- ********************************************************************/
- /********************************************************************
- * *
- * 'PP_LoadData' PowerPacker DATA file support function V1.1 *
- * *
- * You may use this code for non-commercial purposes provided this *
- * copyright notice is left intact ! *
- * *
- * Copyright (c) Aug 1989 by Nico Franτois *
- ********************************************************************/
-
- #include <exec/types.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <functions.h>
-
- #include <ppdata.h>
-
- #define SAFETY_MARGIN 64L
- #define SIZEOF (ULONG)sizeof
- #define myRead(to,len) if (Read (pp_lock, to, len) != len) {\
- pp_FreeStuff(); return (PP_READERR); }
- struct FileLock *pp_lock;
- struct FileInfoBlock *pp_FileInfoBlock;
- UBYTE *pp_filestart;
- ULONG pp_bufferlen;
- UWORD pp_coladdr[4] = { 0xf180, 0xf182, 0xf1a2, 0xf102 };
- UWORD pp_CalcCheckSum();
- ULONG pp_CalcPasskey();
-
- PP_LoadData (pp_file, color, typeofmem, buffer, length, pw) /* Version 1.1 */
- char *pp_file;
- UBYTE color;
- ULONG typeofmem;
- UBYTE **buffer;
- ULONG *length;
- char *pw;
- {
- ULONG hdr, pp_seek;
- UWORD *decrcol, instr, hicol, locol, pp_passchecksum;
- ULONG pp_filelen, pp_crunlen, pp_efficiency;
- UBYTE pp_crunched, pp_crypt = FALSE;
- extern void pp_DecrunchBuffer(), pp_DecrunchColor();
-
- pp_filestart = NULL;
- if (!(pp_FileInfoBlock = (struct FileInfoBlock *)AllocMem
- (SIZEOF(*pp_FileInfoBlock), MEMF_PUBLIC))) return (PP_NOMEMORY);
-
- /* Set decruncher color */
- decrcol = (UWORD *)pp_DecrunchColor;
- if (color != 4) {
- instr = 0x33c9; hicol = 0x00df;
- locol = pp_coladdr[color]; /* = move.w a1,$dff1xx */
- }
- else instr = hicol = locol = 0x4e71; /* nop */
- *decrcol = instr;
- *(decrcol+1) = hicol; *(decrcol+2) = locol;
-
- if (!(pp_lock = (struct FileLock *)Lock (pp_file, ACCESS_READ))) {
- pp_FreeStuff();
- return (PP_LOCKERR);
- }
- Examine (pp_lock, pp_FileInfoBlock);
- UnLock (pp_lock);
- pp_crunlen = pp_FileInfoBlock->fib_Size;
-
- /* read decrunched length */
- if (!(pp_lock = (struct FileLock *)Open (pp_file, MODE_OLDFILE))) {
- pp_FreeStuff();
- return (PP_OPENERR);
- }
- myRead (&hdr, 4L);
-
- /* check if crunched */
- if ((hdr == 'PX20' || hdr == 'PP11' || hdr == 'PP20') && (pp_crunlen>16L)) {
- if (hdr == 'PX20') {
- if (!pw) {
- pp_FreeStuff();
- return (PP_CRYPTED);
- }
- myRead (&pp_passchecksum, 2L);
- if (pp_CalcCheckSum (pw) != pp_passchecksum) {
- pp_FreeStuff();
- return (PP_PASSERR);
- }
- pp_crypt = TRUE;
- pp_seek = 6L;
- }
- else pp_seek = 4L;
- Seek (pp_lock, pp_crunlen - 4L, OFFSET_BEGINNING);
- myRead (&pp_filelen, 4L);
- pp_filelen >>= 8L;
- pp_crunlen -= 4L + pp_seek;
- Seek (pp_lock, pp_seek, OFFSET_BEGINNING);
- myRead (&pp_efficiency, 4L);
- pp_bufferlen = pp_filelen + SAFETY_MARGIN;
- pp_crunched = TRUE;
- }
- else {
- Seek (pp_lock, 0L, OFFSET_BEGINNING);
- pp_bufferlen = pp_filelen = pp_crunlen;
- pp_crunched = FALSE;
- }
- if (!(pp_filestart=(UBYTE *)AllocMem (pp_bufferlen, typeofmem))) {
- pp_FreeStuff();
- return (PP_NOMEMORY);
- }
- /* load file */
- myRead (pp_filestart, pp_crunlen);
-
- Close (pp_lock);
- FreeMem (pp_FileInfoBlock, SIZEOF(*pp_FileInfoBlock));
- if (pp_crunched) {
- if (pp_crypt)
- pp_Decrypt (pp_filestart, pp_crunlen-4L, pp_CalcPasskey (pw));
- pp_DecrunchBuffer (pp_filestart + pp_crunlen,
- pp_filestart + SAFETY_MARGIN, pp_efficiency);
- FreeMem (pp_filestart, SAFETY_MARGIN);
- pp_filestart += SAFETY_MARGIN;
- }
- *buffer = pp_filestart;
- *length = pp_filelen;
- return (PP_LOADOK);
- }
-
- pp_FreeStuff()
- {
- if (pp_lock) Close (pp_lock);
- if (pp_filestart) FreeMem (pp_filestart, pp_bufferlen);
- if (pp_FileInfoBlock) FreeMem (pp_FileInfoBlock, SIZEOF(*pp_FileInfoBlock));
- }
-
- #asm
- ;
- ; PowerPacker Decrunch assembler subroutine V1.1
- ;
- ; call as:
- ; DecrunchBuffer (endcrun, buffer, efficiency);
- ; with:
- ; endcrun : UBYTE * just after last byte of crunched file
- ; buffer : UBYTE * to memory block to decrunch in
- ; efficiency: Longword defining efficiency with wich file was crunched
- ;
- ; NOTE:
- ; Decrunch a few bytes higher (safety margin) than the crunched file
- ; to decrunch in the same memory space. (64 bytes suffice)
- ;
-
- XDEF _pp_DecrunchBuffer
- XDEF _pp_DecrunchColor
- XDEF _pp_CalcCheckSum
- XDEF _pp_CalcPasskey
- XDEF _pp_Decrypt
-
- _pp_DecrunchBuffer:
- move.l 4(a7),a0
- move.l 8(a7),a1
- move.l 12(a7),d0
- movem.l d1-d7/a2-a6,-(a7)
- bsr.s Decrunch
- movem.l (a7)+,d1-d7/a2-a6
- rts
- Decrunch:
- lea myBitsTable(PC),a5
- move.l d0,(a5)
- move.l a1,a2
- move.l -(a0),d5
- moveq #0,d1
- move.b d5,d1
- lsr.l #8,d5
- add.l d5,a1
- move.l -(a0),d5
- lsr.l d1,d5
- move.b #32,d7
- sub.b d1,d7
- LoopCheckCrunch:
- bsr.s ReadBit
- tst.b d1
- bne.s CrunchedBytes
- NormalBytes:
- moveq #0,d2
- Read2BitsRow:
- moveq #2,d0
- bsr.s ReadD1
- add.w d1,d2
- cmp.w #3,d1
- beq.s Read2BitsRow
- ReadNormalByte:
- move.w #8,d0
- bsr.s ReadD1
- move.b d1,-(a1)
- dbf d2,ReadNormalByte
- cmp.l a1,a2
- bcs.s CrunchedBytes
- rts
- CrunchedBytes:
- moveq #2,d0
- bsr.s ReadD1
- moveq #0,d0
- move.b (a5,d1.w),d0
- move.l d0,d4
- move.w d1,d2
- addq.w #1,d2
- cmp.w #4,d2
- bne.s ReadOffset
- bsr.s ReadBit
- move.l d4,d0
- tst.b d1
- bne.s LongBlockOffset
- moveq #7,d0
- LongBlockOffset:
- bsr.s ReadD1
- move.w d1,d3
- Read3BitsRow:
- moveq #3,d0
- bsr.s ReadD1
- add.w d1,d2
- cmp.w #7,d1
- beq.s Read3BitsRow
- bra.s DecrunchBlock
- ReadOffset:
- bsr.s ReadD1
- move.w d1,d3
- DecrunchBlock:
- move.b (a1,d3.w),d0
- move.b d0,-(a1)
- dbf d2,DecrunchBlock
- EndOfLoop:
- _pp_DecrunchColor:
- move.w a1,$dff1a2
- cmp.l a1,a2
- bcs.s LoopCheckCrunch
- rts
- ReadBit:
- moveq #1,d0
- ReadD1:
- moveq #0,d1
- subq.w #1,d0
- ReadBits:
- lsr.l #1,d5
- roxl.l #1,d1
- subq.b #1,d7
- bne.s No32Read
- move.b #32,d7
- move.l -(a0),d5
- No32Read:
- dbf d0,ReadBits
- rts
- myBitsTable:
- dc.b $09,$0a,$0b,$0b
-
- _pp_CalcCheckSum:
- move.l 4(a7),a0
- moveq #0,d0
- moveq #0,d1
- sumloop:
- move.b (a0)+,d1
- beq.s exitasm
- ror.w d1,d0
- add.w d1,d0
- bra.s sumloop
- _pp_CalcPasskey:
- move.l 4(a7),a0
- moveq #0,d0
- moveq #0,d1
- keyloop:
- move.b (a0)+,d1
- beq.s exitasm
- rol.l #1,d0
- add.l d1,d0
- swap d0
- bra.s keyloop
- exitasm:
- rts
- _pp_Decrypt:
- move.l 4(a7),a0
- move.l 8(a7),d1
- move.l 12(a7),d0
- move.l d2,-(a7)
- addq.l #3,d1
- lsr.l #2,d1
- subq.l #1,d1
- encryptloop:
- move.l (a0),d2
- eor.l d0,d2
- move.l d2,(a0)+
- dbf d1,encryptloop
- move.l (a7)+,d2
- rts
- #endasm
-