/*****************************************
 ***
 *** FILE   : VirusTest.c
 *** ------------------------------------
 *** DATE   : 07.08.91
 *** ------------------------------------
 *** AUTHOR : Frank Enderle
 *** ------------------------------------
 *** VERSION: 1.0
 ***
 *****************************************/


#include <exec/types.h>
#include <exec/execbase.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <intuition/intuitionbase.h>

#define WINNAME     "                    W A R N I N G                     "

#define NOERROR     0L
#define ILLEGALMSG  1L
#define NOGFX       2L
#define NOINTUITION 3L
#define NOWINDOW    4L
#define NOFONT      5L

#define QUIT        3L
#define HARDRESET   2L
#define CLRVECS     1L

struct ExecBase         *ExecBase;
struct GfxBase          *GfxBase;
struct IntuitionBase    *IntuitionBase;
struct Window           *MyWin;
struct IntuiMessage     *MyIMsg;
struct TextFont         *MyFont;

extern ULONG            SysBase;

struct Gadget           Gad3    = {NULL,299,148,114,14,GADGHCOMP,
                                   RELVERIFY,BOOLGADGET,NULL,
                                   NULL,NULL,NULL,NULL,QUIT,NULL};
struct Gadget           Gad2    = {&Gad3,162,148,114,14,GADGHCOMP,
                                   RELVERIFY,BOOLGADGET,NULL,
                                   NULL,NULL,NULL,NULL,HARDRESET,NULL};
struct Gadget           Gad1    = {&Gad2,25,148,114,14,GADGHCOMP,
                                   RELVERIFY,BOOLGADGET,NULL,
                                   NULL,NULL,NULL,NULL,CLRVECS,NULL};

struct NewWindow        MyWinNW = {90,5,445,183,-1,-1,GADGETUP,
                                   ACTIVATE|GIMMEZEROZERO,&Gad1,
                                   NULL,(UBYTE *)WINNAME,NULL,NULL,0,0,
                                   0,0,WBENCHSCREEN};

struct TextAttr         MyAttr  = {"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,
                                   FPF_ROMFONT|FPF_DESIGNED};

USHORT  MyCode;
ULONG   MyClass;
APTR    MyAdr;

CheckVecs()
{
 ExecBase = SysBase;
 if(ExecBase->ColdCapture != NULL) return(Virus());
 if(ExecBase->CoolCapture != NULL) return(Virus());
 if(ExecBase->WarmCapture != NULL) return(Virus());
 if(ExecBase->KickMemPtr  != NULL) return(Virus());
 if(ExecBase->KickTagPtr  != NULL) return(Virus());
 if(GetDoIO()        < 0x00f00000) return(Virus());
 if(GetSendIO()      < 0x00f00000) return(Virus());
 if(GetSumKick()     < 0x00f00000) return(Virus());
 return(NOERROR);
}

Virus()
{
 OpenAll();
 SetUpWindow();
 SetUpData();
 FOREVER
 {
  Wait(1L<<MyWin->UserPort->mp_SigBit);
  while(MyIMsg=(struct IntuiMessage *)GetMsg(MyWin->UserPort))
  {
   MyClass = MyIMsg->Class;
   MyCode  = MyIMsg->Code;
   MyAdr   = MyIMsg->IAddress;
   ReplyMsg(MyIMsg);
   switch(MyClass)
   {
    case GADGETUP:  switch((((struct Gadget *)MyAdr)->GadgetID))
                    {
                     case CLRVECS:      ExecBase->ColdCapture = NULL;
                                        ExecBase->CoolCapture = NULL;
                                        ExecBase->WarmCapture = NULL;
                                        ExecBase->KickMemPtr  = NULL;
                                        ExecBase->KickTagPtr  = NULL;
                                        ExecBase->ChkSum      = CheckSum();
                                        ExecBase->KickCheckSum= NULL;
                                        CloseAll();
                                        return(NOERROR);
                                        break;
                     case HARDRESET:    ColdReset();
                                        CloseAll();
                                        return(NOERROR);
                                        break;
                     case QUIT:         CloseAll();
                                        return(NOERROR);
                                        break;
                     default:           CloseAll();
                                        return(ILLEGALMSG);
                                        break;
                    }
                    break;
    default:        CloseAll();
                    return(ILLEGALMSG);
                    break;
   }
  }
 }
}

SetUpData()
{
 Check(ExecBase->ColdCapture,47);
 Check(ExecBase->CoolCapture,57);
 Check(ExecBase->WarmCapture,67);
 Check(ExecBase->KickMemPtr,82);
 Check(ExecBase->KickTagPtr,92);
 CheckDoIO();
 CheckSendIO();
 CheckSumKick();
}

CheckDoIO()
{
 ULONG Buffer;
 UBYTE String[80];
 Buffer = GetDoIO();
 sprintf(String,"($ %08x)",Buffer);
 Print(MyWin,String,325,107,0);
 if(Buffer < 0x00f00000)
  Print(MyWin,"** ALTERED **",189,107,0);
 if(Buffer > 0x00f00000)
  Print(MyWin,"unset",189,107,0);
}

CheckSendIO()
{
 ULONG Buffer;
 UBYTE String[80];
 Buffer = GetSendIO();
 sprintf(String,"($ %08x)",Buffer);
 Print(MyWin,String,325,117,0);
 if(Buffer < 0x00f00000)
  Print(MyWin,"** ALTERED **",189,117,0);
 if(Buffer > 0x00f00000)
  Print(MyWin,"unset",189,117,0);
}

CheckSumKick()
{
 ULONG Buffer;
 UBYTE String[80];
 Buffer = GetSumKick();
 sprintf(String,"($ %08x)",Buffer);
 Print(MyWin,String,325,127,0);
 if(Buffer < 0x00f00000)
  Print(MyWin,"** ALTERED **",189,127,0);
 if(Buffer > 0x00f00000)
  Print(MyWin,"unset",189,127,0);
}

Check(Vec,Line)
ULONG Vec;
SHORT Line;
{
 UBYTE Buffer[80];
 sprintf(Buffer,"($ %08x)",Vec);
 Print(MyWin,Buffer,325,Line,0);
 if(Vec == NULL)
  Print(MyWin,"unset",189,Line,0);
 if(Vec != NULL)
  Print(MyWin,"** ALTERED **",189,Line,0);
}

SetUpWindow()
{
 Box(MyWin,22,146,141,163);
 Box(MyWin,159,146,278,163);
 Box(MyWin,296,146,415,163);
 Print(MyWin,"Some System Vectors are not default. Check if there",0,8,1);
 Print(MyWin,"are running resident programs !",0,20,1);
 Print(MyWin,"ColdCapture        :",21,47,0);
 Print(MyWin,"CoolCapture        :",21,57,0);
 Print(MyWin,"WarmCapture        :",21,67,0);
 Print(MyWin,"KickMemPtr         :",21,82,0);
 Print(MyWin,"KickTagPtr         :",21,92,0);
 Print(MyWin,"DoIO               :",21,107,0);
 Print(MyWin,"SendIO             :",21,117,0);
 Print(MyWin,"SumKickData        :",21,127,0);
 Print(MyWin,"CLR VECTORS",37,151,0);
 Print(MyWin,"HARD RESET",181,151,0);
 Print(MyWin,"It's OK",327,151,0);
}

OpenAll()
{
 IntuitionBase          =   OpenLibrary("intuition.library",NULL);
   if(IntuitionBase == NULL) { CloseAll(); return(NOINTUITION); }
 GfxBase                =   OpenLibrary("graphics.library",NULL);
   if(GfxBase       == NULL) { CloseAll(); return(NOGFX);       }
 MyWin                  =   OpenWindow(&MyWinNW);
   if(MyWin         == NULL) { CloseAll(); return(NOWINDOW);    }
 MyFont                 =   OpenFont(&MyAttr);
   if(MyFont        == NULL) { CloseAll(); return(NOFONT);      }
 SetFont(MyWin->RPort,MyFont);
}

CloseAll()
{
 if(MyWin)                  CloseWindow(MyWin);
 if(MyFont)                 CloseFont(MyFont);
 if(IntuitionBase)          CloseLibrary(IntuitionBase);
 if(GfxBase)                CloseLibrary(GfxBase);
 return();
}

Box(Win,x1,y1,x2,y2)
struct Window *Win;
SHORT x1,y1,x2,y2;
{
 SetDrMd(Win->RPort,JAM1);
 SetAPen(Win->RPort,1);
 Move(Win->RPort,x1,y1);
 Draw(Win->RPort,x2,y1);
 Draw(Win->RPort,x2,y2);
 Draw(Win->RPort,x1,y2);
 Draw(Win->RPort,x1,y1);
 Move(Win->RPort,x2+1,y1);
 Draw(Win->RPort,x2+1,y2);
 Move(Win->RPort,x1-1,y1);
 Draw(Win->RPort,x1-1,y2);
 SetAPen(Win->RPort,2);
 Move(Win->RPort,x2+2,y1+1);
 Draw(Win->RPort,x2+2,y2+1);
 Move(Win->RPort,x2+3,y1+1);
 Draw(Win->RPort,x2+3,y2+1);
 Draw(Win->RPort,x1+2,y2+1);
}

Print(Win,msg,x,y,c)
struct Window *Win;
STRPTR msg;
SHORT  x,y;
BOOL   c;
{
 SHORT SLen,Len;
 SetDrMd(Win->RPort,JAM1);
 SetAPen(Win->RPort,2);
 SLen = strlen(msg);
 Len  = ((Win->Width-TextLength(Win->RPort,msg,SLen))/2)-2;
 if(c == 0)
  Move(Win->RPort,x+2,y+Win->RPort->TxBaseline+1);
 if(c == 1)
  Move(Win->RPort,Len+2,y+Win->RPort->TxBaseline+1);
 Text(Win->RPort,msg,strlen(msg));
 SetAPen(Win->RPort,1);
 if(c == 0)
  Move(Win->RPort,x,y+Win->RPort->TxBaseline);
 if(c == 1)
  Move(Win->RPort,Len,y+Win->RPort->TxBaseline);
 Text(Win->RPort,msg,strlen(msg));
}

#asm
            public  _GetDoIO
            public  _GetSendIO
            public  _GetSumKick
            public  _CheckSum
            public  _ColdReset

            public  _LVODoIO
            public  _LVOSendIO
            public  _LVOSumKick
            public  _LVOSuperState

_GetDoIO:   movem.l a1-a6,-(a7)
            move.l  _SysBase,a6
            lea     _LVODoIO(a6),a1
            lea     2(a1),a2
            move.l  (a2),d0
            movem.l (a7)+,a1-a6
            rts

_GetSendIO: movem.l a1-a6,-(a7)
            move.l  _SysBase,a6
            lea     _LVOSendIO(a6),a1
            lea     2(a1),a2
            move.l  (a2),d0
            movem.l (a7)+,a1-a6
            rts

_GetSumKick:
            movem.l a1-a6,-(a7)
            movem.l _SysBase,a6
            lea     _LVOSumKick(a6),a1
            lea     2(a1),a2
            move.l  (a2),d0
            movem.l (a7)+,a1-a6
            rts

_CheckSum:  movem.l a0-a6/d1-d7,-(a7)
            move.l  _SysBase,a6
            lea     34(a6),a1
            move.l  #22,d0
            move.l  #0,d1
Chk:        add     (a1)+,d1
            dbf     d0,Chk
            not     d1
            move.l  d1,d0
            movem.l (a7)+,a0-a6/d1-d7
            rts

_ColdReset: movem.l a0-a6,-(a7)
            move.l  _SysBase,a6
            jsr     _LVOSuperState(a6)
            not.l   38(a6)
            jmp     $FC0000
            movem.l (a7)+,a0-a6
            rts

#endasm
