;--------------------------------------------------------------------------
;	  Demo-programme for the 'removelink.library'
;		Written (and © Johan Ohman 1993)
;
;		    DetQuick version 2.04
;--------------------------------------------------------------------------

VER:	macro
	dc.b	'2.04'
	endm

	incdir	sys:include/
	include	rll/removelink.i
	include	rll/doshunks.i
	include	rll/removelink_lib.i
	include	libraries/dos_lib.i
	include	libraries/dos.i
	include	libraries/dosextens.i
	include	exec/memory.i
	include	exec/exec_lib.i

CALL:	macro
	jsr	_LVO\1(a6)
	endm

s:	movem.l	d0-a6,-(sp)
	move.l	4.w,a6
	suba.l	a1,a1
	CALL	FindTask
	move.l	d0,a4

	tst.l	pr_CLI(a4)
	bne.b	.CLI_ACTIVE

	lea.l	pr_MsgPort(a4),a1
	CALL	WaitPort
	lea.l	pr_MsgPort(a4),a1
	CALL	GetMsg

.CLI_ACTIVE:
	movem.l	(sp)+,d0-a6

	movem.l	d0/a0,-(sp)
	move.l	4.w,a6
	lea.l	DosLib(pc),a1
	CALL	OldOpenLibrary
	move.l	d0,DosBase
	movem.l	(sp)+,d0/a0

	move.l	a0,ArgA0
	move.l	d0,ArgD0
	
	subq.l	#1,d0
	beq.w	NoArgs

	clr.b	(a0,d0.l)

.OpenRL:
	move.l	4.w,a6
	lea.l	RLLib(pc),a1
	moveq.l	#32,d0
	CALL	OpenLibrary
	move.l	d0,RLBase
	tst.l	d0
	bne.b	.ChangeDir

	pea.l	RLLib(pc)
	pea.l	_NoLib(pc)
	bsr.w	PrintF
	addq.l	#8,Sp
	rts
	
.ChangeDir:
	move.l	DosBase(pc),a6
	move.l	ArgA0(pc),d1
	moveq.l	#ACCESS_READ,d2
	CALL	Lock
	tst.l	d0
	beq.w	CloseLibs

	move.l	d0,MyLock
	move.l	d0,d1
	CALL	CurrentDir
	move.l	d0,OldLock
	
	move.l	DosBase(pc),a6
	move.l	MyLock(pc),d1
	move.l	#MyFileInfoBlock,d2
	CALL	Examine

	lea.l	MyFileInfoBlock+FIB_FileName,a0
	move.l	a0,-(sp)
	pea.l	_DiskName(pc)
	bsr.w	PrintF
	addq.l	#8,sp

	move.l	4.w,a6			;So the user should be able to interrupt
	moveq.l	#SIGBREAKB_CTRL_C,d0	;scan ...
	CALL	AllocSignal

ContinueScan:
	move.l	4.w,a6
	moveq.l	#0,d0
	moveq.l	#0,d1
	CALL	SetSignal
	andi.l	#SIGBREAKF_CTRL_C,d0
	tst.l	d0
	bne.w	Interrupted

	move.l	DosBase(pc),a6
	move.l	MyLock(pc),d1
	move.l	#MyFileInfoBlock,d2
	CALL	ExNext
	cmp.l	#-1,d0
	bne.w	ScanDiskError

	lea.l	MyFileInfoBlock,a0
	tst.w	FIB_DirEntryType(a0)
	bmi.b	File

	lea.l	MyFileInfoBlock,a0
	pea.l	FIB_FileName(a0)
	pea.l	_DIR(pc)
	bsr.w	PrintF
	addq.l	#8,Sp
	bra.b	ContinueScan

File:	lea.l	MyFileInfoBlock,a0
	cmp.w	#FIBF_READ,FIB_Protection(a0)
	bne.b	.GoOn

	lea.l	MyFileInfoBlock+FIB_FileName,a0
	move.l	a0,-(sp)
	pea.l	_FileProtected(pc)
	bsr.w	PrintF
	addq.l	#8,Sp
	bra.b	ContinueScan

.GoOn:
	lea.l	MyFileInfoBlock+FIB_FileName,a0
	bsr.w	LoadFile
	tst.l	d0
	bpl.b	.Exec

	addq.l	#1,d0
	beq.b	.NotExec

	lea.l	FIB_FileName(a0),a0
	move.l	Mem(pc),-(sp)
	move.l	FIB_FileName(a0),-(sp)
	pea.l	_NotEnoghMem(pc)
	bsr.w	PrintF
	lea.l	12(sp),sp
	bra.w	ContinueScan

.NotExec:
	lea.l	MyFileInfoBlock+FIB_FileName,a0
	move.l	a0,-(sp)
	pea.l	_NotExec(pc)
	bsr.w	PrintF
	addq.l	#8,sp
	bra.w	ContinueScan

.Exec:

;------------------------------------------------------------------------------
;	This is where we use the 'removelink.library' to check for
;	viruses linked up with the current file.
;	We only get the name. We don't repair the file (although we can
;	use the library for that too...).
;------------------------------------------------------------------------------

	move.l	RLBase(pc),a6
	CALL	AllocRLMem
	move.l	d0,RLMemPtr

	move.l	RLMemPtr(pc),a0
	move.l	Mem(pc),RL_BufferLen(a0)
	move.l	FileMemPtr(pc),RL_BufferPtr(a0)
	move.l	RLBase(pc),a6
	CALL	GetFileVName

	tst.l	RL_FileInfection(a0)
	beq.b	.NotInfected

	move.l	RL_FileInfection(a0),a1
	move.l	FI_VirusName(a1),-(sp)

	lea.l	MyFileInfoBlock+FIB_FileName,a0
	move.l	a0,-(sp)

	pea.l	_FileInfection(pc)
	bsr.w	PrintF
	lea.l	12(sp),Sp
	bra.b	.End

.NotInfected:
	lea.l	MyFileInfoBlock,a0
	lea.l	MyFileInfoBlock+FIB_FileName,a0
	move.l	a0,-(sp)
	pea.l	_NotInfected(pc)
	bsr.b	PrintF
	addq.l	#8,sp

.End:	bsr.w	ReturnRL
	bsr.w	ReturnFileMem
	bra.w	ContinueScan

NoArgs:
	pea.l	RLLib(pc)
	pea.l	_NoArgs(pc)
	bsr.b	PrintF
	addq.l	#8,Sp
	rts

ScanDiskError:
	CALL	IoErr
	cmp.l	#ERROR_NO_MORE_ENTRIES,d0
	beq.b	ScanComplete

	pea.l	_ScanDiskError(pc)
	bsr.b	PrintF
	addq.l	#4,Sp
	rts

ScanComplete:
	pea.l	_ScanComplete(pc)
	bsr.b	PrintF
	addq.l	#4,Sp

	move.l	OldLock(pc),d1
	move.l	DosBase(pc),a6
	CALL	CurrentDir

	move.l	MyLock(pc),d1
	move.l	DosBase(pc),a6
	CALL	UnLock

CloseLibs:
	move.l	DosBase(pc),a1
	move.l	4.w,a6
	CALL	CloseLibrary

	Move.l	RLBase(pc),d0
	beq.b	.Not1
	move.l	d0,a1
	CALL	closelibrary
.Not1:	rts

Interrupted:
	pea.l	_C(pc)
	bsr.b	PrintF
	addq.l	#4,Sp
	bra.b	ScanComplete

PrintF:
	movem.l	d0-a6,-(Sp)
	move.l	4.w,a6
	move.l	15*4+4*1(Sp),a0
	lea.l	15*4+4*2(Sp),a1	
	lea.l	.SubPrintF(pc),a2
	link	a5,#-512
	move.l	a5,a3
	lea.l	-512(a3),a3
	jsr	_LVORawDoFMT(a6)
	movem.l	d0-a6,-(sp)
	lea.l	-512(a5),a5
	move.l	DosBase(pc),a6
	jsr	-60(a6)
	move.l	d0,d1
	move.l	a5,d2
.1:	tst.b	(a5)+
	bne.b	.1
	move.l	a5,d3
	sub.l	d2,d3
	jsr	-48(a6)
	movem.l	(Sp)+,d0-a6

	unlk	a5
	movem.l	(Sp)+,d0-a6
	rts

.SubPrintF:
	move.b	d0,(a3)+
	rts

;------------------------------------------------------------------------------
;	Smart(er)Loader 1.10:
;	Checks if the the file is executable,
;
;				if - read the first hunk of the file
;				if not - just give a message
;
;	Don't worry if you don't understand all.
;	It only reads the first hunk of a file.
;------------------------------------------------------------------------------


LoadFile:
LF_Size=	6*4
	movem.l	d1-a6,-(sp)
	moveq.l	#0,d5		;Flag

	move.l	a0,d1
	move.l	#MODE_OLDFILE,d2
	CALL	Open
	tst.l	d0
	beq.b	.OpenError
	move.l	d0,d4

	lea.l	HeaderBytes,a5
	move.l	d4,d1
	move.l	a5,d2
	moveq.l	#LF_Size,d3
	CALL	read
	cmp.l	#HUNK_HEADER,(a5)
	bne.b	.NotExec	;We don't have to read this file no more

	move.l	2*4(a5),d1	;Nr of hunks
	move.l	5*4(a5),d0	;Hunk1 size
	lsl.l	#2,d0		;into bytes

	;We don't even have to load anything more than 
	;the first raw hunk. Not even the Reloc32Tables ...

	lea.l	5*4(a5,d1.l),a4
	lea.l	2*4(a4,d0.l),a4
	sub.l	a5,a4
	addq.l	#4,a4
	move.l	a4,Mem

	move.l	d4,d1
	moveq.l	#0,d2
	moveq.l	#OFFSET_BEGINING,d3
	CALL	Seek

	move.l	a4,d0
	moveq.l	#MEMF_PUBLIC,d1
	move.l	4.w,a6
	CALL	AllocMem
	tst.l	d0
	beq.b	.MemError

	move.l	d0,FileMemPtr
	move.l	d0,d2
	move.l	a4,d3
	move.l	d4,d1
	move.l	DosBase(pc),a6
	CALL	Read
	move.l	d0,d5

.End:	move.l	d4,d1
	CALL	Close

	move.l	d5,d0
	movem.l	(sp)+,d1-a6
	rts

.NotExec:
	moveq.l	#-1,d5
	bra.b	.End

.MemError:
	moveq.l	#-2,d5
	bra.b	.End

.OpenError:
	moveq.l	#-3,d5
	bra.b	.End

ReturnFileMem:
	move.l	FileMemPtr(pc),a1
	move.l	Mem(pc),d0
	move.l	4.w,a6
	CALL	FreeMem
	rts

ReturnRL:
	move.l	RLMemPtr(pc),a0
	move.l	RLBase(pc),a6
	CALL	FreeRLMem
	rts

ArgA0:		dc.l	0
ArgD0:		dc.l	0
DosBase:	dc.l	0
RLBase:		dc.l	0
MyLock:		dc.l	0
FileMemPtr:	dc.l	0
RLMemPtr:	dc.l	0
OldLock:	dc.l	0
Mem:		dc.l	0

RLLib:		RLNAME
DosLib:		DOSNAME

_NoArgs:	dc.b	10
		dc.b	'DetQuick v '
		Ver
		dc.b	' (C) Johan Öhman 1993',10
		dc.b	'Args:	RemQuick [Volume], to check all file on Volume'
		dc.b	10
		dc.b	'(This programme requires ''%s'' 32.00 or higher )',10,0
		dc.b	10,0

_C:		dc.b	'^C (Scan interrupted) ',10,0
_NoLib:		dc.b	'Sorry, I couldn''t find %s ...',10,0
_ScanDiskError:	dc.b	'An error occured during scan...',10,0
_ScanComplete	dc.b	'Disk-scan finished ',10,0

_FileProtected:	dc.b	'%30s	[Protected, can''t read]',10,0
_DIR:		dc.b	$9b,'0;33;40m'
		dc.b	'%30s	[DIR]',10
		dc.b	$9b,'0;31;40m',0

_NotEnoghMem:	dc.b	'%30s	[Not enough memory (%ld required)]'
_NotExec:	dc.b	'%30s	[DATA FILE]',10,0
_NotInfected:	dc.b	'%30s	[Not Infected]',10,0
_FileInfection:	dc.b	'%30s	[Infected by '
		dc.b	$9b,'3;30;41m'
		dc.b	'''%s'''
		dc.b	$9b,'0;31;40m]',10,0

_DiskName:	dc.b	10
		dc.b	'DiskName:	%30s',10,10,0


	section	SomeThing,BSS_P

MyFileInfoBlock:ds.l	300/4
HeaderBytes:	ds.l	6
