; VDEngine for Slayer
; Slayer - a desktop anti-virus for RISC OS
; Copyright (C) 1996 - 2000 Kiwi Software (UK)
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; any later version.
;
; This program 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 General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
;
; info@kiwisoft.co.uk
; -------------------------------------------------------------------------



; designed for extASM or similar
; assumes 1K descending stack in R13 on entry (ie use from BASIC)

#smile		;sad but true
#speed 2500
#set fileCache = 0

TEMP 		r12

#include 	"VDEng:main.h.Aliases"
#include 	"VDEng:main.h.MiscDefine"
#include 	"SlayEng:h.VirusIDs"
#include	"SlayEng:h.macros"
#include	"VDEng:main.h.macros"


; main entry point
; =>	r1 Pointer to name of file to be scanned
;	r2 0 for file +ve = size of memory block
;	r3 load address
;	r4 filelength
;	r5 filetype

; <= 	r0 Result of check
;	/no/ other registers preserved

; free regs are: r9, r10, r11, r12(temp)
; usable regs are: r0-r6
; /must/ preserve r7, r8

 		stmfd	r13!,{r14}

		; we don't need the following for Slayer...
		;cmp	r2,#-1
		;beq	scan_from_filehandle

		;teq	r2,#0
		;bne	memory_block_scan

 ; grab file info, then open the file

		; why the fuck doesn't this work. :p
		;ldr	r0, [r3, #12]
		;tst	r0, #1	; test bit 0; owner read access
		;strne	r0, oldFileFlags ; it's not allowed; keep old flags
		;movne	r0, #4	; set file attributes
		; filename already in r1
		;movne	r5, #%00110011
		;swine	XOS_File
		;bicvs	pc, pc, #&80000000
		;bvs	exitFromError

		ldr	filelength,[r3, #8]
		cmp	filelength,#MINIMUM_SIZE_CHECKED
		blt	exit ;don't bother checking anything
		;movlt	r0,#no_virus
		;ldmltfd	r13!,{pc}	;don't bother checking anything

		;ldr	r12, [r3, #12]	; file attributes
		;tst	r12, #0		; have we got read-access?
		;streq	r12, oldFileFlags ; store the old ones...
		;stmeqfd	r13!, {r0, r4}
		; moveq	r0, #4 ; write attributes for named file
		; moveq	r4, #33 ; nice flags :)
		; swieq	OS_File
		;ldmeqfd	r13!, {r0, r4}

		ldr	filetype,[r3, #20]	;&FFFFFFFF if not typed (-1)
		ldr	r3,[r3, #0]

 		;mov	r0,#5			;read catalogue info
 		;swi	XOS_File
 		;mvnvs	r0,#0
 		;ldmvsfd	r13!,{pc}		;error - leave
 		;mov	filelength,r4		;length

; calculate the filetype
		;mov	filetype,r5
		;mov	r0,#&FFF00
		;and	filetype,r3,r0
		;mov	filetype,filetype, lsr #8

 ; now look to see if this is a file we are interested in

		;mov	r9,r3,lsr #20	;check load address for brb virus
		;teq	r9,#&FFF	;if top 12 bits set then it is a filetype - we want a load address
		;teqne	r0,r0		;bogde to set eq flag

;icon 2218, satani, MonitorDAT, vandamme, all thunder and honeymonster are covered by the following
 		cmp	filelength,#1208+1024	;<1215+1024 could be thunder
		ble	grabIt

		teq	filetype,#&FF8		;absolute
		teqne	filetype,#&FFA		;module

 ; check filesizes
 		teqne	filelength,#5036	;5036 Nitemare
 		teqne	filelength,#2616	;2616 icon
 		teqne	filelength,#2618	;2618 icon
 		teqne	filelength,#2644	;2644 icon
 		teqne	filelength,#3639	;3639 icon
 		teqne	filelength,#5587	;5587 icon
 		teqne	filelength,#5592	;5592 icon
 		teqne	filelength,#5859	;5859 icon
 		teqne	filelength,#7463	;7463 icon
 		teqne	filelength,#7696	;7696 icon
 		teqne	filelength,#7933	;7933 icon
 		teqne	filelength,#5574	;5574 icon
 		teqne	filelength,#4301	;4301 icon
 		teqne	filelength,#4325	;4325 icon
 		teqne	filelength,#2438	;2438 datadqm
 		teqne	filelength,#2432	;2462 datadqm (vigay)
		teqne	filelength,#2311	;2311 datadqm
 		teqne	filelength,#5580	;5580 bigfoot
 		teqne	filelength,#5535	;5535 bigfoot
 		teqne	filelength,#2355	;2355 monitorDAT

 ; now filetypes

		;cmnne	filetype,#0	;be right back
		teqne	filetype,#&FAF		;HTML
		teqne	filetype,#&ae4		;Java class
 		;teqne	filetype,#&FFB		;BASIC
 		;teqne	filetype,#&FF9		;sprite
 		;teqne	filetype,#&FFD		;data
 		;teqne	filetype,#&FFF		;text

; if not wanted then exit
		bne	exit
 		;movne	r0,#no_virus
 		;ldmnefd	r13!,{pc}		;unstack and return to caller

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Pre checks complete. This is a file worthy of our attention - grab it

.grabIt

#if fileCache == 1
		;mov	r12, r1			; backup filename pointer
		mov	r0, #24			; read natural block size
		swi	XOS_File
		bvs	exitFromError

		mov	r0, r1
		mov	r1, r2
		swi	&73142			;XFileCache_Open

		mov	r0, r1			; copy cache handle
#else
; open the file
 		mov	r0,#&40			;open for read
 		swi	XOS_Find
 		;blvs	checkForAccess
 		bvs	exitFromError
 		mov	r1,r0
#endif
; read first and last xxx bytes
#if fileCache

		mov	r0, r1
		adr	r1, bufferTopOfFile
		mov	r2, #FILE_TOP_BUFFER_SIZE
		mov	r3, #0
		swi	&73144			;XFileCache_ReadData
		bvs	exitFromError
#else
 		mov	r0,#3			;read bytes
 		;r1 already contains file handle
 		adr	r2,bufferTopOfFile
 		mov	r3,#FILE_TOP_BUFFER_SIZE
 		mov	r4,#0
 		swi	XOS_GBPB
 		bvs	exitFromError
#endif

#if fileCache

 		adr	r1,bufferBottomOfFile
 		mov	r2,#FILE_BOTTOM_BUFFER_SIZE
		sub	r3,filelength,r2

 		;file might not be big enough...
 		cmp	filelength,r2
 		sublt	r2,r2,filelength	;filelength-buffer size
 		addlt	r1,r1,r2	;add that to buffer pointer
		movlt	r3,#0		;read from start
		movlt	r2,filelength	;read /all/ bytes from file

		swi	&73144		;XFileCache_ReadData
 		bvs	exitFromError
#else
 		;r1 already contains file handle
 		adr	r2,bufferBottomOfFile
 		mov	r3,#FILE_BOTTOM_BUFFER_SIZE
		sub	r4,filelength,r3

 		;file might not be big enough...
 		cmp	filelength,r3
 		sublt	r3,r3,filelength	;filelength-buffer size
 		addlt	r2,r2,r3	;add that to buffer pointer
		movlt	r4,#0		;read from start
		movlt	r3,filelength	;read /all/ bytes from file

 		mov	r0,#3			;read bytes
 		swi	XOS_GBPB
 		bvs	exitFromError
#endif
; close the file (no longer needed)
#if fileCache
		teq	r0, #0			;is the file still open?
		swi	&73143			;XFileCache_Close
		bvs	exitFromError
#else
 		teq	r1,#0			;is the file still open
 		movne	r0,#0
 		swine	XOS_Find		;close it
 		bvs	exitFromError
#endif
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; We have the memory, now do the actual checks

#include 	"VDEng:main.s.VCheck"

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; no virus found - leave

.exit
 		;ldr	r12, oldFileFlags
		;cmn	r12, #0
		;stmnefd	r13!, {r0, r4}
		; movne	r0, #4
		; movne	r5, r12
		; swine	XOS_File
		; bvs	exitFromError
		; bicvs	pc, pc, #&80000000
		;ldmnefd	r13!, {r0, r4}
		;mvnne	r12, #0
		;strne	r12, oldFileFlags
		;bl	checkForRestoreAccess

 		mov	r0,#no_virus
 		ldmfd	r13!,{pc}		;unstack and return to caller

.checkForAccess
		stmfd	r13!, {r1}
		ldr	r1, [r0]
		teq	r1, #67773	; 'The access details set for this
					;  item do not allow this'

		ldmfd	r13!, {r1}	; different error...
		bne	exitFromError

		; right then...
		; set the accesses to something nice

		stmfd	r13!, {r0, r2 - r4}
		mov	r0, #5
		swi	XOS_File
		ldmfd	r13!, {r0, r2 - r4}

		str	r5, oldAccessFlags

		stmfd	r13!, {r0, r2 - r4}
		mov	r0, #4		; write just the access details
		mov	r5, #%00110011
		swi	XOS_File
		ldmfd	r13!, {r0, r2 - r4}

		movs	pc, r14

.checkForRestoreAccess
		stmfd	r13!, {r0}

		ldr	r0, oldAccessFlags
		teq	r0, #-1

		ldmfd	r13!, {r0}
		moveqs	pc, r14

		stmfd	r13!, {r0, r2 - r5}

		mov	r0, #4
		ldr	r5, oldAccessFlags
		swi	XOS_File

		mov	r0, #-1
		str	r0, oldAccessFlags

		ldmfd	r13!, {r0, r2 - r5}

		movs	pc, r14

.oldAccessFlags
		dcd	-1

.exitFromError
		ldr	r12, oldFileFlags
		cmn	r12, #0
		stmnefd	r13!, {r0, r4}
		 movne	r0, #4
		 movne	r5, r12
		 swine	XOS_File
		ldmnefd	r13!, {r0, r4}
		mvnne	r12, #0
		strne	r12, oldFileFlags

		;mov	r0,#no_virus
		;bl	checkForRestoreAccess
		ldmfd	r13!,{pc}

.oldFileFlags	dcd	0
.niceFileFlags	dcd	33

#if fileCache
.fileNamePtr	dcd	0
#endif

#include 	"VDEng:VCheck.h.Includes"
 		align
#include	"VDEng:main.s.MemBlockS"
#include	"VDEng:main.s.FHandScan"
;#include 	"VDEng:VCheck.s.Buffers"
 		align


