/*
 Viruscan.c - Controlla bootblock, ExecBase e RAM
*/

#include <exec/types.h>
#include <exec/execbase.h>
#include <libraries/dos.h>
#include <exec/io.h>
#include <devices/trackdisk.h>
#include <ctype.h>
#include <stdio.h>

#ifdef LATTICE
#define NUMHEADS 2 /* Numero lati disco */
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#else
#include <functions.h> /* Funzioni Aztec C */
#endif

#define BLOCKSIZE 1024     /* Dimensione buffer */

extern struct ExecBase *SysBase;
struct MsgPort         *diskport;
struct IOStdReq        *diskreq;

BYTE  diskbuffer[ BLOCKSIZE ]; /* Buffer disco */
void cleanup( s,c ) /* Gestione di errori ed uscita */
char *s; LONG c; /* Messaggio di errore, codice ritorno */
{
 puts( s );
 puts( "\nVIRUSCAN V1.8 - By Luigi Callegari\n" );
 exit( c );
}

void Displayb( l ) /* Mostra il buffer in ASCII */
int l;
{
 register int i, c;

 for ( i = 0 ; i < l ; i++ ) 
   putchar( ( ( c = diskbuffer[i])>31 && c<128 ) ? c : '.' );
 return;
}

void ReadCylSec( cyl, sec, hd ) /* Lettura random del disco */
SHORT cyl, sec, hd; /* Cilindro, settore, facciata disco */
{
 LONG offset;
 diskreq -> io_Length   = BLOCKSIZE;
 diskreq -> io_Data     = (APTR) diskbuffer;
 diskreq -> io_Command  = CMD_READ;
 offset = TD_SECTOR * (sec+ NUMSECS*hd +NUMSECS*NUMHEADS*cyl);
 diskreq -> io_Offset   = offset;
 DoIO( diskreq ); /* Richiede operazione di I/O */

 if ( diskreq -> io_Error )
   cleanup( "Errore dalla periferica!", 2L );
 return;
}

void MotorOn()  /* Accende il motore del drive */
{
 diskreq -> io_Length  = 1;
 diskreq -> io_Command = TD_MOTOR;
 DoIO( diskreq );
}

void MotorOff()  /* Spegne il motore del drive */
{
 diskreq -> io_Length  = 0;
 diskreq -> io_Command = TD_MOTOR;
 DoIO( diskreq );
}

void main( argc, argv )
int argc; char *argv[];
{
register int i, ndisk, error;

 if ( argc != 2 ) /* Se sbagliata sintassi */
   cleanup( "\nUso: Viruscan n (n = 0,1,2,3,4 = RAM)", 3L );

 ndisk = atoi( argv[1] ); /* Converte in numero intero */

 /** Qui si verificano i vettori modificati dai virus **/

 if ( SysBase -> ColdCapture != NULL )
   printf( "!!ColdCapture = %lx\n", SysBase -> ColdCapture );

 if ( SysBase -> CoolCapture != NULL )
   printf( "!!CoolCapture = %lx\n", SysBase -> CoolCapture );

 if ( SysBase -> WarmCapture != NULL )
   printf( "!!WarmCapture = %lx\n", SysBase -> WarmCapture );

 if ( ndisk < 0 || ndisk > 4 )
   cleanup("\nVIRUSCAN: Numero drive non compreso tra 0 e 4!",\
          4L );

 if ( ndisk == 4 ) /* Se parametro di chiamata RAM */
 {
   puts("\n\033[1mVIRUSCAN\033[0m: RAM (0x7ec00..0x7efff):\n");
   movmem( (char *)0x7ec00, (char *)diskbuffer, BLOCKSIZE);
   Displayb( BLOCKSIZE );
   cleanup( "\n\nLavoro eseguito, tutto OK!\n", 0L );
 }

 diskport  =  CreatePort(0,0);
 diskreq   =  CreateStdIO( diskport );
 if ( error = OpenDevice( TD_NAME, ndisk, diskreq, 0 ) )
   cleanup( "\nVIRUSCAN: Periferica inapribile!", error );

 printf("\n\033[1mVIRUSCAN\033[0m: Scansione DF%d:\n\n", ndisk );
 MotorOn();
 for ( i = 0; i < 2 ; i++) /* Legge due blocchi */
 {
   ReadCylSec(0, i, 0);
   Displayb(TD_SECTOR);
 }
 MotorOff(); CloseDevice( diskreq );
 DeleteStdIO( diskreq ); DeletePort( diskport );
 cleanup( "\n\nLavoro eseguito, tutto OK!\n", 0L );
}
