home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !MAGS / ICTARI / ICTARI42.ZIP / ASSEMBLY / VIRUS.S / LVF_FFF.S next >
Text File  |  2004-03-07  |  44KB  |  1,026 lines

  1. *************************************************
  2. * Link-Virus-Finder V1.5                        *
  3. * and Fast-File-Finder V1.5                     *
  4. * (c)1989 by Maxon Computer                     *
  5. * by  Σ-soft, Markus Fritze                     *
  6. * developed with Turbo-Ass V1.4                 *
  7. *************************************************
  8. ;switches:
  9. virus           EQU 0
  10. ;0:Fast-File-Finder, <>0:Link-Virus-Finder
  11.  
  12.                 IF virus
  13.                 OUTPUT 'LVF.TTP' ;Link-Virus-Finder
  14.                 ELSE
  15.                 OUTPUT 'FFF.TTP' ;Fast-File-Finder
  16.                 ENDC
  17.                 OPT F+,W+        ;Warnings on,Fast-Load on
  18.  
  19. max_prgs        EQU 1000         ;maximum of 1000 Programs in the LVF
  20. max_sectorsize  EQU 8192         ;maximum Sectorsize
  21.  
  22. ;A6-Register points to the BSS-Segment
  23.                 BASE A6,BSS
  24.  
  25. ;Define Structure of the BIOS-Parameter-Block
  26.                 PART 'BPB-Structure'
  27.                 RSRESET
  28. recsiz:         RS.W 1          ;Bytes per Sector
  29. clsiz:          RS.W 1          ;Sectors per Cluster
  30. clsizb:         RS.W 1          ;Bytes per Cluster
  31. rdlen:          RS.W 1          ;Length of the Root-Directories
  32. fsiz:           RS.W 1          ;Length of a FAT
  33. fatrec:         RS.W 1          ;Startsector of the 2.FAT
  34. datrec:         RS.W 1          ;Startsector of the 1.free Sectors
  35. numcl:          RS.W 1          ;Entire number of Clusters
  36. bflags:         RS.W 1          ;Bit0=1 with 16-bit-FAT
  37.                 ENDPART
  38.  
  39. _drvbits        EQU $04C2       ;The Bitmask of the Drive
  40.  
  41.                 PART 'main'
  42. start:
  43.         movea.l         4(SP),A0        ;Pointer to the Basepage
  44.         movea.l         $18(A0),A6      ;Pointer to the BSS-Area
  45.         lea             own_stack(PC),SP
  46.  
  47.         pea             init_text(PC)
  48.         bsr             print_line      ;Startup-Message
  49.  
  50.                 IF virus
  51.         lea             data_buff(A6),A0
  52.         move.l          A0,data_base(A6)
  53.  
  54.         clr.w           -(SP)
  55.         pea             fname(A6)
  56.         move.w          #$3D,-(SP)
  57.         trap            #1              ;Fopen()
  58.         addq.l          #8,SP
  59.         move.l          D0,D7
  60.         bmi.s           start1          ;Error
  61.         move.l          data_base(A6),-(SP)
  62.         move.l          #max_prgs*32,-(SP)
  63.         move.w          D7,-(SP)
  64.         move.w          #$3F,-(SP)
  65.         trap            #1              ;Fread() - Read Datablock 
  66.         lea             12(SP),SP
  67.         move.w          D7,-(SP)
  68.         move.w          #$3E,-(SP)
  69.         trap            #1              ;Fclose()
  70.         addq.l          #4,SP
  71. start1:
  72.                 ENDC
  73.  
  74.         bsr             convert         ;utilize Command line 
  75.  
  76.         clr.l           -(SP)
  77.         move.w          #$20,-(SP)
  78.         trap            #1              ;to supervisor mode 
  79.         move.l          D0,2(SP)
  80.         move.l          _drvbits.w,D7   ;read out Variable 
  81.         trap            #1              ;to User mode again
  82.         addq.l          #6,SP
  83.         move.w          D7,D1           ;_drvbits to D1
  84.  
  85.                 IF !virus
  86.         lea             search_mask(A6),A1  ;Search mask
  87.         lea             search_chars(A6),A2 ;Search data
  88.                 ENDC
  89.         moveq           #$18,D7         ;Ignore Directory & Vol-Label
  90.         moveq           #0,D5           ;Bytes of the files found
  91.         moveq           #0,D4           ;Number of files found
  92.         moveq           #0,D3           ;Number of folders
  93.  
  94.         moveq           #2,D2           ;go on with Drive C 
  95.         tst.w           D6              ;no drive specified?
  96.         bmi.s           loop            ;Exactly! =>
  97.         move.w          D6,D2           ;test the special drive
  98. loop:
  99.         btst            D2,D1           ;Drive available?
  100.         beq.s           loop1           ;No! =>
  101.         movea.l         #stack,A0
  102.         adda.l          A6,A0
  103.         move.l          A0,stack_pnt(A6) ;put stack back
  104.         move.w          D2,D0
  105.         bsr             set_drive       ;Set Drive,read FAT 
  106.         movem.l         D1-D3,-(SP)
  107.         move.l          D0,D1
  108.         pea             drive_text(PC)
  109.         bsr             print_line
  110.         moveq           #'A',D0
  111.         add.b           D2,D0
  112.         bsr             chrout          ; output actual Drive 
  113.         pea             drive_text2(PC)
  114.         bsr             print_line
  115.         moveq           #7,D2           ;maximum of 8 places output
  116.         bsr             dec_out         ;release memory
  117.         pea             drive_text3(PC)
  118.         bsr             print_line      ;"Bytes free"
  119.         movem.l         (SP)+,D1-D3
  120.  
  121.         bsr             read_dir        ;read in complete Tree
  122.  
  123.         lea             path(A6),A3
  124.         move.b          #'A',(A3)
  125.         add.b           D2,(A3)+        ;find out drive
  126.         move.b          #':',(A3)+
  127.         move.b          #'\',(A3)+      ;Set Root-Path 
  128.  
  129.         move.w          D1,-(SP)
  130.         bsr             hunt_dir        ;search through Tree
  131.         move.w          (SP)+,D1
  132. loop1:
  133.         tst.w           D6              ;Drive info?
  134.         bpl.s           loop2           ;Yes! => Ready
  135.         addq.w          #1,D2
  136.         cmp.w           #32,D2          ;up to Bit 32 will not be all
  137.         bne.s           loop            ;exponents yet? Correct! =>
  138. loop2:
  139.                 IF virus
  140.         moveq           #0,D1
  141.         move.w          virus_count(A6),D1 ;Virus found?
  142.         beq.s           loop3              ;No! =>
  143.         moveq           #4,D2              ;maximum of 5 places output
  144.         bsr             dec_out
  145.         pea             virus_text(A6)
  146.         bsr             print_line         ;attempted files found
  147. loop3:
  148.                 ENDC
  149.         moveq           #0,D1
  150.         move.w          D4,D1           ;Number of 'Hits'
  151.         moveq           #5,D2           ;maximum of 6 places output
  152.         bsr             dec_out
  153.         pea             files_text(A6)
  154.         bsr             print_line
  155.         move.l          D5,D1           ;Length of all the files together
  156.         moveq           #7,D2           ;maximum of 8 places output
  157.         bsr             dec_out
  158.         pea             files_text2(A6)
  159.         bsr             print_line
  160.  
  161.         moveq           #0,D1
  162.         move.w          D3,D1           ;Number of folders
  163.         moveq           #4,D2           ;maximum of 5 places output
  164.         bsr             dec_out
  165.         pea             folders_text(A6)
  166.         bsr.s           print_line
  167.  
  168.         move.w          #7,-(SP)
  169.         trap            #1              ;Wait on a key
  170.         addq.l          #2,SP
  171.                 IF virus
  172.         bclr            #5,D0
  173.         cmp.b           #'J',D0         ;Write?
  174.         bne.s           _exit           ;No! =>
  175.  
  176.         movea.l         data_base(A6),A4
  177.         movea.l         A4,A3           ;Mark Data base 
  178. code:
  179.         tst.l           (A4)            ;End of the List?
  180.         beq.s           code2           ;Yes! =>
  181.         lea             24(A4),A4
  182.         bra.s           code
  183. code2:
  184.         suba.l          A3,A4           ;Length of all Data
  185.  
  186.         clr.w           -(SP)
  187.         pea             fname(A6)
  188.         move.w          #$3C,-(SP)
  189.         trap            #1              ;Fcreate()
  190.         addq.l          #8,SP
  191.         move.l          D0,D7
  192.         bmi.s           _exit           ;Error
  193.         move.l          A3,-(SP)        ;Base address of the Data
  194.         move.l          A4,-(SP)        ;Length
  195.         move.w          D7,-(SP)
  196.         move.w          #$40,-(SP)
  197.         trap            #1              ;Fwrite()
  198.         lea             12(SP),SP
  199.         move.w          D7,-(SP)
  200.         move.w          #$3E,-(SP)
  201.         trap            #1              ;Fclose()
  202.         addq.l          #4,SP
  203.                 ENDC
  204.  
  205. _exit:
  206.         pea             exit_text(A6)
  207.         bsr.s           print_line      ;Cursor out again, etc.
  208.  
  209.         clr.w           -(SP)
  210.         trap            #1              ;Program end
  211.                 ENDPART
  212.  
  213. *************************************************
  214. * String sent to the Stack                      *
  215. *************************************************
  216.                 PART 'print_line'
  217. print_line:
  218.         movem.l         D0-D2/A0-A2,-(SP)
  219.         move.l          4+6*4(SP),-(SP)
  220.         move.w          #$09,-(SP)
  221.         trap            #1              ;Cconws()
  222.         addq.l          #6,SP
  223.         movem.l         (SP)+,D0-D2/A0-A2
  224.         move.l          (SP)+,(SP)      ;Stack correction
  225.         rts
  226.                 ENDPART
  227. *************************************************
  228. * Characters given in D0                        *
  229. *************************************************
  230.                 PART 'chrout'
  231. chrout:
  232.         movem.l         D0-D2/A0-A2,-(SP)
  233.         move.w          D0,-(SP)
  234.         move.w          #$02,-(SP)
  235.         trap            #1              ;Cconout()
  236.         addq.l          #4,SP
  237.         movem.l         (SP)+,D0-D2/A0-A2
  238.         rts
  239.                 ENDPART
  240. **********************************************
  241. * positive Decimal-Number in D1              *
  242. * without leading zeros given                *
  243. * maximum number of places minus 1 in D2     *
  244. **********************************************
  245.                 PART 'dec_out'
  246. dec_out:
  247.         movem.l         D0-D4/A1,-(SP)
  248.         lea             dec_tab(PC),A1  ;Pointer to the Table
  249.         move.w          D2,D0           ;Number of places-1
  250.         add.w           D0,D0           ;times 4
  251.         add.w           D0,D0           ;(faster than LSL.W #2,D0!)
  252.         lea             4(A1,D0.w),A1   ;Pointer to the place number
  253.         moveq           #0,D4           ;ignore leading zeros
  254. dec_out1:
  255.         move.l          -(A1),D3        ;Tables value
  256.         moveq           #-'0',D0        ;will be -'1',-'2',-'3',...
  257. dec_out2:
  258.         sub.l           D3,D1           ;SUB until an occurence
  259.         dbcs            D0,dec_out2     ;Occurrence? No! =>
  260.         neg.w           D0              ;e.g. -'1' => '1'
  261.         cmp.b           #'0',D0         ;a zero?
  262.         beq.s           dec_out4        ;Yes! =>
  263.         moveq           #-1,D4          ;from here will also be zeros
  264. dec_out3:
  265.         bsr.s           chrout          ;Character given in D0 
  266. dec_out5:
  267.         add.l           D3,D1           ;the occurrence returns
  268.         dbra            D2,dec_out1     ;all places already?
  269.         movem.l         (SP)+,D0-D4/A1
  270.         rts
  271. dec_out4:
  272.         tst.b           D4              ;Zeros given?
  273.         bne.s           dec_out3        ;Yes! =>
  274.         tst.w           D2              ;last digit?
  275.         bne.s           dec_out5        ;No! => then ignore
  276.         moveq           #'0',D0         ;when the entire value is 0 ,
  277.         bra.s           dec_out3        ;at least a 0 is given!
  278. dec_tab:
  279.                 DC.L 1,10,100,1000,10000,100000
  280.                 DC.L 1000000,10000000,100000000,1000000000
  281.                 ENDPART
  282. *************************************************
  283. * convert() - Utilize the Commandline           *
  284. *                                               *
  285. * With it the variable "flag" will be set,      *
  286. * the D6-Register (Drive) defined and the       *
  287. * Search mask and the Search string from the    *
  288. * File names put together.                      *
  289. *************************************************
  290.                 PART 'convert'
  291. convert:
  292.         lea             start-128+1(A6),A0 ;Commandline
  293.         clr.b           flag(A6)           ;remove all Flags
  294.         moveq           #-1,D6             ;no drive given
  295. convert1:
  296.         cmpi.b          #' ',(A0)+         ;Miss spaces
  297.         beq.s           convert1
  298.         subq.l          #1,A0
  299.         cmpi.b          #'-',(A0)          ;anything following?
  300.         bne.s           convert2           ;No! =>
  301.         addq.l          #1,A0
  302.         bset            #0,flag(A6)        ;Count files only
  303. convert2:
  304.         cmpi.b          #' ',(A0)+         ;Miss spaces
  305.         beq.s           convert2
  306.         subq.l          #1,A0
  307.                 IF virus
  308.         cmpi.b          #'+',(A0)          ;anything following?
  309.         bne.s           convert3           ;No! =>
  310.         addq.l          #1,A0
  311.         bset            #1,flag(A6)        ;take on all files
  312. convert3:
  313.         cmpi.b          #' ',(A0)+         ;Miss spaces
  314.         beq.s           convert3
  315.         subq.l          #1,A0
  316.         cmpi.b          #':',(A0)
  317.         bne.s           convert8
  318.         addq.l          #1,A0              ;Ignore colon
  319. convert8:
  320.         moveq           #0,D0
  321.         move.b          (A0),D0
  322.         bmi.s           convert14          ;Code>127 => no Drive
  323.         bclr            #5,D0
  324.         subi.b          #'A',D0
  325.         bmi.s           convert14          ;<'A' => no Drive
  326.         cmp.b           #32,D0
  327.         bhs.s           convert14          ;>maxdrive => no Drive
  328.         move.w          D0,D6              ;mark Drive given
  329. convert14:
  330.         rts
  331.                 ELSE
  332.         cmpi.b          #':',(A0)
  333.         bne.s           convert6
  334.         moveq           #0,D0
  335.         move.b          1(A0),D0
  336.         addq.l          #2,A0
  337.         bclr            #5,D0
  338.         cmp.b           #32,D0
  339.         bhs.s           convert6            ;>maxdrive => no Drive
  340.         move.w          D0,D6               ;Mark Drive given
  341. convert6:
  342.         cmpi.b          #' ',(A0)+          ;Miss spaces
  343.         beq.s           convert6
  344.         subq.l          #1,A0
  345.         lea             search_mask(A6),A1  ;Search mask
  346.         lea             search_chars(A6),A2 ;Search data
  347.         clr.l           (A1)+
  348.         clr.l           (A1)+               ;remove all Search masks
  349.         clr.l           (A1)
  350.         subq.l          #8,A1
  351.         moveq           #0,D2               ;no Allquantor
  352.         moveq           #7,D1               ;maximum of 8 character Filename
  353. convert7:
  354.         move.b          (A0)+,D0
  355.         beq             convert19           ;End of the Filenames
  356.         cmp.b           #' ',D0             ;Space as End?
  357.         beq             convert19           ;Yes! =>
  358.         cmp.b           #13,D0              ;CR as End?
  359.         beq             convert19           ;Yes! =>
  360.         cmp.b           #'.',D0             ;Start of the Extension?
  361.         beq.s           convert12           ;Yes! =>
  362.         cmp.b           #'?',D0             ;Existence quantor?
  363.         bne.s           convert8            ;No! =>
  364.         tst.w           D2                  ;Allquantor already given?
  365.         bne.s           convert11           ;Yes! =>
  366.         sf              (A1)+
  367.         sf              (A2)+               ;Ignore character
  368.         bra.s           convert11           ;continue =>
  369. convert8:
  370.         cmp.b           #'*',D0             ;Allquantor?
  371.         bne.s           convert9            ;No! =>
  372.         moveq           #-1,D2              ;Allquantor
  373.         bra             convert7
  374. convert9:
  375.         tst.w           D2                  ;Allquantor already given?
  376.         bne.s           convert11           ;Yes! =>
  377.         cmp.b           #'a',D0
  378.         blo.s           convert10
  379.         cmp.b           #'z',D0
  380.         bhi.s           convert10
  381.         bclr            #5,D0               ;Change to capital letters
  382. convert10:
  383.         move.b          D0,(A2)+            ;take on characters
  384.         st              (A1)+               ;Set Mask with it
  385. convert11:
  386.         dbra            D1,convert7         ;maximum of 8 characters
  387.         bra             convert13
  388. convert12:
  389.         tst.w           D2                  ;Allquantor given?
  390.         bne             convert13           ;Yes! =>
  391.         move.b          #' ',(A2)+          ;Filenames with ' '
  392.         st              (A1)+               ;fill up
  393.         dbra            D1,convert12
  394. convert13:
  395.         lea             search_mask+8(A6),A1  ;Search mask
  396.         lea             search_chars+8(A6),A2 ;Search data
  397.         moveq           #2,D1                 ;maximum 3 character extension
  398. convert14:
  399.         move.b          (A0)+,D0
  400.         beq.s           convert17             ;End of the Filenames
  401.         cmp.b           #' ',D0               ;Space as End?
  402.         beq.s           convert17             ;Yes! =>
  403.         cmp.b           #13,D0                ;CR as End?
  404.         beq.s           convert17
  405.         cmp.b           #'?',D0               ;Existence quantor?
  406.         bne.s           convert15             ;No! =>
  407.         sf              (A1)+
  408.         sf              (A2)+                 ;Ignore characters
  409.         bra.s           convert18             ;continue =>
  410. convert15:
  411.         cmp.b           #'*',D0               ;Allquantor?
  412.         beq             convert19             ;No! =>
  413.         cmp.b           #'a',D0
  414.         blo.s           convert16
  415.         cmp.b           #'z',D0
  416.         bhi.s           convert16
  417.         bclr            #5,D0                 ;change to capital letters
  418. convert16:
  419.         move.b          D0,(A2)+              ;take on characters
  420.         st              (A1)+                 ;Set Mask with it
  421.         dbra            D1,convert14          ;already all maximum 8 characters
  422.         bra             convert19
  423. convert17:
  424.         move.b          #' ',(A2)+            ;Fill in Extension
  425.         st              (A1)+                 ;with spaces
  426. convert18:
  427.         dbra            D1,convert17
  428. convert19:
  429.         rts
  430.                 ENDC
  431.                 ENDPART
  432. *************************************************
  433. * hunt_dir() - Complete Directory-Tree in A0    *
  434. * searched through, the number of entries in    *
  435. * the Directory are placed in D0 with it.       *
  436. *                                               *
  437. * this Routine calls on itself recursively,     *
  438. * to also search through any low level folders  *
  439. * as well.                                      *
  440. *                                               *
  441. * The Tree must through read_dir() lie in       *
  442. * memory, i.e. ready with Pointers chained      *
  443. * to it.                                        *
  444. *************************************************
  445.                 PART 'hunt_dir'
  446. hunt_dir:
  447.         subq.w          #1,D0           ;for DBRA
  448. hunt_dir1:
  449.         move.w          D7,D1           ;Illegal File attribute-Bits
  450.         and.b           11(A0),D1       ;Flags for it
  451.         bne             hunt_dir3       ;File not found! =>
  452.         cmpi.b          #$E5,(A0)       ;Deleted file?
  453.         beq             hunt_dir2       ;Yes! =>
  454.                 IF !virus
  455.         move.l          (A0),D1
  456.         beq             hunt_dir4       ;End of the Directories =>
  457.         and.l           (A1),D1
  458.         cmp.l           (A2),D1         ;Characters 1-4 of the File names
  459.         bne             hunt_dir3
  460.         move.l          4(A0),D1
  461.         and.l           4(A1),D1
  462.         cmp.l           4(A2),D1        ;Characters 5-8 of the File names
  463.         bne             hunt_dir3
  464.         move.l          8(A0),D1
  465.         and.l           8(A1),D1
  466.         cmp.l           8(A2),D1        ;Compare the Extension
  467.         bne             hunt_dir3
  468.         btst            #0,flag(A6)     ;Count only files?
  469.         bne.s           print_fname4    ;Yes! =>
  470.         bsr             print_fname     ;Filenames given
  471. print_fname4:
  472.         addq.w          #1,D4           ;Count files
  473.         movep.w         31(A0),D1
  474.         move.b          30(A0),D1
  475.         swap            D1              ;File length
  476.         movep.w         29(A0),D1       ;from Intel
  477.         move.b          28(A0),D1       ;to 68000
  478.         add.l           D1,D5           ;for the entire length
  479.                 ELSE
  480.         tst.b           (A0)
  481.         beq             hunt_dir4       ;End of the Directories =>
  482.         addq.w          #1,D4           ;one more file found
  483.         move.w          8(A0),D1        ;keep characters 1+2 of the Extension
  484.         cmp.w           #'PR',D1        ;PRG, PRX, etc.
  485.         beq.s           found_file
  486.         cmp.w           #'TO',D1        ;TOS
  487.         beq.s           found_file
  488.         cmp.w           #'TT',D1        ;TTP
  489.         beq.s           found_file
  490.         cmp.w           #'AC',D1        ;ACC, ACX, etc.
  491.         beq.s           found_file
  492.         cmp.w           #'AP',D1        ;APP
  493.         beq.s           found_file
  494.         cmp.w           #'DR',D1        ;DRV (Driver)
  495.         beq.s           found_file
  496.         cmp.w           #'SY',D1        ;SYS (Disk driver!)
  497.         bne             hunt_dir3
  498. found_file:
  499.         move.l          D0,-(SP)
  500. regs            REG D1-D4/D6-A2/A4-A6
  501.         movem.l         regs,-(SP)
  502.         movep.w         27(A0),D0
  503.         move.b          26(A0),D0         ;Cluster in Intel-Format
  504.         move.w          drive(A6),-(SP)   ;actual Drive
  505.         subq.w          #2,D0
  506.         mulu            clsiz(A5),D0      ;times Sectors per Cluster
  507.         add.w           datrec(A5),D0     ;+ first free Sector
  508.         move.w          D0,-(SP)          ;= absolute Sector
  509.         move.w          #1,-(SP)          ;read in a Sector
  510.         pea             sector_buffer(A6) ;to the Buffer
  511.         move.l          #$040000,-(SP)
  512.         trap            #13               ;Rwabs() - Read in a Sector
  513.         lea             14(SP),SP
  514.         tst.l           D0
  515.         bmi             _exit
  516.         lea             sector_buffer(A6),A2
  517.         moveq           #0,D0
  518.         cmpi.w          #$601A,(A2)       ;Program known?
  519.         bne.s           count_loop1       ;No! =>
  520.         lea             28(A2),A0         ;Pointer to the Program start
  521.         cmpi.w          #$487A,(A0)+      ;PEA
  522.         bne.s           no_virus          ;No! =>
  523.         cmpi.w          #$FFFE,(A0)+      ;*-2(PC)
  524.         bne.s           no_virus          ;No! =>
  525.         cmpi.w          #$4EF9,(A0)       ;c't-Virus?
  526.         beq             virus2            ;YES! =>>
  527.         cmpi.l          #$207A0006,(A0)+  ;VCS-Virus?
  528.         bne.s           no_virus          ;No! =>
  529.         cmpi.l          #$4EFB8800,(A0)
  530.         beq             virus1            ;YES! =>>
  531. no_virus:
  532.         moveq           #127,D2
  533. count_loop:
  534.         eor.w           D2,D0             ;Calculate checksum
  535.         sub.w           (A2)+,D0
  536.         addq.w          #1,D0
  537.         dbra            D2,count_loop
  538.         tst.w           D0
  539.         bne.s           count_loop1
  540.         moveq           #213,D0           ;The checksum is NEVER 0!
  541. count_loop1:
  542.         movem.l         (SP),regs         ;Checksum in D0
  543.         tst.l           D0                ;Checksum=0?
  544.         beq             check_it6         ;then no Program! =>
  545.  
  546.         movea.l         data_base(A6),A1
  547.         bra.s           check_it0
  548. check_it2:
  549.         lea             24(A4),A1         ;the next entry
  550.         movea.l         A2,A0             ;return to the Filenames
  551. check_it0:
  552.         movea.l         A0,A2             ;A0 save
  553.         movea.l         A1,A4             ;A1 save
  554.         tst.l           (A1)              ;Table is empty, i.e. End
  555.         beq.s           check_it3         ;New Entry necessary! =>
  556.         moveq           #4,D1             ;only 10(!) Letters
  557. check_it1:
  558.         cmpm.w          (A1)+,(A0)+       ;compare
  559.         dbne            D1,check_it1
  560.         bne.s           check_it2         ;unequal =>
  561.  
  562.         lea             10(A4),A1         ;Pointer to the checksum
  563.         moveq           #6,D1             ;maximum of 7 Checksums
  564. check_it5:
  565.         tst.w           (A1)
  566.         beq.s           check_it4         ;Checksum not found
  567.         cmp.w           (A1)+,D0
  568.         dbeq            D1,check_it5      ;continue with compare =>
  569.         lea             -12(A1),A1
  570.         beq.s           check_it8         ;Checksum is ok! =>
  571. check_it4:
  572.         movea.l         A2,A0
  573.         bsr             print_fname       ;Filenames given
  574.         pea             fehler_text(A6)
  575.         bsr             print_line        ;Make report!
  576.         btst            #1,flag(A6)       ;always take it on?
  577.         bne.s           check_it7         ;Yes! =>
  578.         movem.l         D0/D2/A0-A2,-(SP)
  579.         move.w          #7,-(SP)
  580.         trap            #1                ;Wait on a Keypress
  581.         addq.l          #2,SP
  582.         bclr            #5,D0
  583.         move.w          D0,D1
  584.         movem.l         (SP)+,D0/D2/A0-A2
  585.         cmp.b           #'J',D1           ;take it on?
  586.         bne.s           check_it6         ;No! =>
  587. check_it7:
  588.         move.w          D0,(A1)           ;Copy checksum
  589.         addq.w          #1,D5
  590.         bra.s           check_it6
  591.  
  592. check_it3:
  593.         move.l          (A2)+,(A4)+       ;new entry
  594.         move.l          (A2)+,(A4)+       ;Copy filenames
  595.         move.w          (A2)+,(A4)+       ;(only 10 Letters!)
  596.         move.w          D0,(A4)           ;1st Checksum
  597.         addq.w          #1,D5
  598.         movem.l         (SP),regs
  599.         bsr             print_fname       ;Filenames given
  600.         pea             new_text(A6)
  601.         bsr             print_line
  602.         bra.s           check_it6
  603. check_it8:
  604.         btst            #0,flag(A6)       ;Output?
  605.         bne.s           check_it6         ;No! =>
  606.         movem.l         (SP),regs
  607.         bsr             print_fname       ;Filenames given
  608.         bra.s           check_it6
  609.  
  610. virus1:
  611.         movem.l         (SP),regs          ;Filenames to A0
  612.         lea             virus1_text(A6),A4 ;VCS-Linkvirus
  613.         bra.s           check_it9
  614. virus2:
  615.         movem.l         (SP),regs          ;Filenames to A0
  616.         lea             virus2_text(A6),A4 ;Milzbrand-Virus
  617. check_it9:
  618.         bsr.s           print_fname        ;Fname given
  619.         pea             virus_text(A6)
  620.         bsr             print_line         ;Make report!
  621.         move.l          A4,-(SP)
  622.         bsr             print_line
  623.         addq.w          #1,virus_count(A6) ;Virus numbers
  624. check_it6:
  625.         movem.l         (SP)+,regs
  626.         move.l          (SP)+,D0
  627.                 ENDC
  628. hunt_dir3:
  629.         btst            #4,11(A0)       ;A directory?
  630.         beq.s           hunt_dir2       ;No! =>
  631.         cmpi.b          #$E5,(A0)       ;Deleted?
  632.         beq.s           hunt_dir2       ;Yes! =>
  633.         cmpi.w          #'. ',(A0)
  634.         beq.s           hunt_dir2       ;Ignore Dummy-Entries
  635.         cmpi.w          #'..',(A0)
  636.         beq.s           hunt_dir2
  637.         movem.l         D0/A0/A3,-(SP)
  638.                 REPT 8
  639.         move.b          (A0)+,(A3)+
  640.                 ENDR
  641.         move.b          #'.',(A3)+
  642.                 REPT 3
  643.         move.b          (A0)+,(A3)+     ;Copy to the Path
  644.                 ENDR
  645.         addq.l          #1,A0
  646.         move.b          #'\',(A3)+
  647.         move.l          (A0)+,D0        ;Tree length in entries
  648.         movea.l         (A0),A0
  649.         bsr             hunt_dir
  650.         addq.w          #1,D3           ;INC Number of directories
  651.         movem.l         (SP)+,D0/A0/A3
  652. hunt_dir2:
  653.         lea             32(A0),A0       ;=> next entry
  654.         dbra            D0,hunt_dir1    ;through all entries?
  655. hunt_dir4:
  656.         rts
  657.                 ENDPART
  658. *************************************************
  659. * Filenames given from A0                       *
  660. *************************************************
  661.                 PART 'print_fname'
  662. print_fname:
  663.         movem.l         D0-D2/A0-A3,-(SP)
  664.                 REPT 8
  665.         move.b          (A0)+,(A3)+     ;Filenames
  666.                 ENDR
  667.         move.b          #'.',(A3)+
  668.                 REPT 3
  669.         move.b          (A0)+,(A3)+     ;append to the Path
  670.                 ENDR
  671.         btst            #4,(A0)         ;A folder?
  672.         beq.s           print_fname0
  673.         move.b          #'\',(A3)+      ;then also to conclude
  674. print_fname0:
  675.         move.b          #13,(A3)+       ;CR
  676.         move.b          #10,(A3)+       ;LF
  677.         clr.b           (A3)
  678.         lea             path(A6),A3
  679. print_fname1:
  680.         moveq           #0,D0
  681.         move.b          (A3)+,D0        ;fetch character
  682.         beq.s           print_fname2    ;End of the Paths =>
  683.         cmp.b           #' ',D0         ;Ignore spaces
  684.         beq.s           print_fname1    ;next character =>
  685.         cmp.b           #'.',D0         ;Extension reached?
  686.         bne.s           print_fname3    ;No! =>
  687.         cmpi.b          #' ',(A3)       ;it follows a " "?
  688.         beq.s           print_fname1    ;then ignore "." it
  689. print_fname3:
  690.         bsr             chrout          ;the character given
  691.         bra.s           print_fname1
  692. print_fname2:
  693.         movem.l         (SP)+,D0-D2/A0-A3
  694.         rts
  695.                 ENDPART
  696. *************************************************
  697. * read_dir() - Read in complete Directory-Tree  *
  698. *             (in A0 it sits, Length in D0)     *
  699. * This routine reads the Root-Directory in      *
  700. * and then calls with each Directory,on the     *
  701. * routine "read_sub_dir", which it itself can   *
  702. * recursively call upon again.                  *
  703. *************************************************
  704.                 PART 'read_dir'
  705. read_dir:
  706.         movem.l         D1-D7/A1-A6,-(SP)
  707.         move.w          rdlen(A5),D0    ;Length of the Root-Directory
  708.         mulu            recsiz(A5),D0   ;times Sector size
  709.         bsr             get_mem         ;memory requisition
  710.         movea.l         D0,A4           ;Pointer to the ROOT-Directory
  711.         movea.l         D0,A3           ;Start of the Root-Directory
  712.         move.w          drive(A6),-(SP) ;actual Drive
  713.         move.w          fatrec(A5),D1
  714.         add.w           fsiz(A5),D1
  715.         move.w          D1,-(SP)        ;Start sector of the Root-Directory
  716.         move.w          rdlen(A5),-(SP) ;Length of the FAT
  717.         move.l          A4,-(SP)        ;in the Buffer
  718.         move.l          #$040000,-(SP)
  719.         trap            #13             ;Rwabs() - Read in DIR 
  720.         lea             14(SP),SP
  721.         tst.l           D0
  722.         bmi             _exit
  723.         move.w          rdlen(A5),D7    ;Length of the Root-Directory
  724.         mulu            recsiz(A5),D7   ;times Sector size
  725.         lsr.l           #5,D7           ;\32 Bytes (Entry sizee)
  726.         subq.w          #1,D7           ;Entire number of entries-1
  727. hunt_dir_loop:
  728.         btst            #4,11(A4)       ;A directory?
  729.         beq.s           hunt_dir_loop1  ;No! =>
  730.         cmpi.b          #$E5,(A4)       ;deleted directory?
  731.         beq.s           hunt_dir_loop1  ;Yes! =>
  732.         bsr.s           read_sub_dir
  733. hunt_dir_loop1:
  734.         lea             32(A4),A4       ;next entry
  735.         dbra            D7,hunt_dir_loop ;all Entries
  736.         movea.l         A3,A0           ;Start address of the Directories
  737.         move.w          rdlen(A5),D0    ;Length of the Directories in Bytes
  738.         mulu            recsiz(A5),D0   ;calculate
  739.         lsr.l           #5,D0           ;\32 Bytes (Entry size)
  740.         movem.l         (SP)+,D1-D7/A1-A6
  741.         rts
  742.                 ENDPART
  743. *************************************************
  744. * read_sub_dir() - Sub-directories from A4      *
  745. *                  recursively read in,         *
  746. * A4 points to the directory, that it should    *
  747. * be read from. It determines the Cluster       *
  748. * number, then goes on.  With "hunt_dir" ,      *
  749. * "hunt_dir" all the correct entries are there, *
  750. * all of the entries will be chained through    *
  751. * (Pointers) Long words. Placed with it in the  *
  752. * directory entries(32 Bytes long) at Offset    *
  753. * 16 is a Longword, which points to the         *
  754. * directory. At Offset 20 is the maximum number *
  755. * of entries that the directory can possibly    *
  756. * have. This will be given from "hunt_dir"      *
  757. * as likewise required.                         *
  758. *************************************************
  759.                 PART 'read_sub_dir'
  760. read_sub_dir:
  761.         movem.l         D0-A6,-(SP)
  762.         movep.w         27(A4),D3
  763.         move.b          26(A4),D3       ;Cluster number in Intel-Format
  764.         movea.l         A4,A3           ;Mark Pointer to the Main directory
  765.         moveq           #0,D5           ;Cluster number of the Sub-Directories
  766. read_sub_dir1:
  767.         moveq           #0,D0
  768.         move.w          clsizb(A5),D0   ;Bytes per Cluster
  769.         bsr             get_mem         ;Requisition memory
  770.         movea.l         D0,A4           ;Pointer to the Cluster
  771.         tst.w           D5
  772.         bne.s           read_sub_dir5
  773.         move.l          A4,16(A3)       ;Pointer to the Sub-Directory
  774. read_sub_dir5:
  775.         move.w          drive(A6),-(SP) ;actual Drive
  776.         move.w          D3,D0           ;actual Cluster number
  777.         subq.w          #2,D0
  778.         mulu            clsiz(A5),D0    ;times Sectors per Cluster
  779.         add.w           datrec(A5),D0   ;+ first free Sector
  780.         move.w          D0,-(SP)        ;= absolute Sector
  781.         move.w          clsiz(A5),-(SP) ;Read in cluster
  782.         move.l          A4,-(SP)        ;to the Buffer
  783.         move.l          #$040000,-(SP)
  784.         trap            #13             ;Rwabs() - Read in cluster 
  785.         lea             14(SP),SP
  786.         tst.l           D0
  787.         bmi             _exit
  788.  
  789.         move.w          clsizb(A5),D7   ;Bytes per Cluster
  790.         lsr.w           #5,D7           ;\32 Bytes (Entry size)
  791.         subq.w          #1,D7           ;for DBRA
  792. read_sub_dir2:
  793.         btst            #4,11(A4)       ;a directory?
  794.         beq.s           read_sub_dir3   ;No! =>
  795.         cmpi.b          #$E5,(A4)       ;deleted?
  796.         beq.s           read_sub_dir3   ;Yes! =>
  797.         cmpi.w          #'. ',(A4)
  798.         beq.s           read_sub_dir3   ;ignore Dummy-Entries
  799.         cmpi.w          #'..',(A4)
  800.         beq.s           read_sub_dir3
  801.         bsr.s           read_sub_dir
  802. read_sub_dir3:
  803.         lea             32(A4),A4        ;next entry
  804.         dbra            D7,read_sub_dir2 ;all Entries
  805.         addq.w          #1,D5            ;Cluster number of the Sub-Directory
  806.         move.w          D3,D0
  807.         add.w           D0,D0           ;times 2, as pointer to the FAT
  808.         movea.l         fat_adr(A6),A0  ;Pointer: decoded FAT
  809.         move.w          0(A0,D0.w),D3   ;Number of the following clusters
  810.         bpl.s           read_sub_dir1   ;End? No! =>
  811.  
  812.         mulu            clsizb(A5),D5   ;Bytes per Cluster
  813.         lsr.l           #5,D5           ;Size of the Sub-Directory in Bytes
  814.         move.l          D5,12(A3)       ;Number of possible entries
  815.         movem.l         (SP)+,D0-A6
  816.         rts
  817.                 ENDPART
  818. *************************************************
  819. * Report Drive in D0 as actual Drive, read in   *
  820. * FAT. The memory space free will be returned   *
  821. * in  D0.                                       *
  822. * IMPORTANT: A5 points with "set_drive" ALWAYS  *
  823. *      to the BPB of the actual Drives.         *
  824. *      The outcome of it will be in "read_dir". *
  825. *************************************************
  826.                 PART 'set_drive'
  827. set_drive:
  828.         movem.l         D1-A4,-(SP)
  829.         move.w          D0,drive(A6)    ;set actual Drive
  830.         bsr.s           get_bpb         ;fetch Bios Parameter Block-Address
  831.  
  832.         moveq           #0,D0
  833.         move.w          numcl(A5),D0
  834.         add.l           D0,D0           ;Entire number of the Clusters*2
  835.         bsr             get_mem         ;Requisition memory
  836.         move.l          D0,fat_adr(A6)
  837.  
  838.         move.w          fsiz(A5),D0     ;Length of the FAT
  839.         mulu            recsiz(A5),D0   ;times Bytes per Sector
  840.         bsr             get_mem         ;Requisition memory
  841.         move.l          D0,fat_buffer(A6)
  842.  
  843.         move.w          drive(A6),-(SP)  ;actual Drive
  844.         move.w          fatrec(A5),-(SP) ;Start of the 2nd FAT
  845.         move.w          fsiz(A5),-(SP)   ;Length of the FAT
  846.         move.l          fat_buffer(A6),-(SP)
  847.         move.l          #$040000,-(SP)
  848.         trap            #13              ;2nd FAT completely read in.
  849.         lea             14(SP),SP
  850.         tst.l           D0
  851.         bmi             _exit
  852.  
  853.         bsr.s           change_fat      ;FAT in 68000-Format
  854.  
  855.         movea.l         fat_adr(A6),A0  ;Pointer: decoded FAT
  856.         addq.l          #4,A0           ;ignore first 2 Clusters
  857.         move.w          numcl(A5),D1
  858.         subq.w          #3,D1           ;subtract 2 Clusters (DBRA!)
  859.         moveq           #0,D0           ;Number of free Clusters
  860. set_drive1:
  861.         tst.w           (A0)+           ;a free Cluster?
  862.         bne.s           set_drive2      ;No! =>
  863.         addq.w          #1,D0           ;INC free Cluster
  864. set_drive2:
  865.         dbra            D1,set_drive1   ;all counted?
  866.         mulu            clsizb(A5),D0   ;times Bytes per Cluster
  867.         movem.l         (SP)+,D1-A4
  868.         rts
  869.                 ENDPART
  870. *************************************************
  871. * BPB of the actual Drives to A5                *
  872. *************************************************
  873.                 PART 'get_bpb'
  874. get_bpb:
  875.         move.w          drive(A6),-(SP)
  876.         move.w          #7,-(SP)
  877.         trap            #13             ;Getbpb(drive)
  878.         addq.l          #4,SP
  879.         move.l          D0,act_bpb(A6)
  880.         beq             _exit
  881.         movea.l         D0,A5           ;Pointer to the BPB
  882.         rts
  883.                 ENDPART
  884. *************************************************
  885. * FAT of the 12-bit- i.e. 16-bit-Intel-Format   *
  886. * in 16-bit-68000-Format                        *
  887. *************************************************
  888.                 PART 'change_fat'
  889. change_fat:
  890.         movea.l         fat_buffer(A6),A0 ;Pointer: FAT
  891.         movea.l         fat_adr(A6),A1    ;Pointer: decoded FAT
  892.         move.w          fsiz(A5),D0       ;Length of the FAT
  893.         mulu            recsiz(A5),D0     ;times Bytes per Sector
  894.         move.w          bflags(A5),D1     ;Fetch Flags
  895.         btst            #0,D1             ;12-bit-FAT?
  896.         beq.s           change_fat2       ;Yes! =>
  897.         lsr.w           #1,D0             ;Number of Words
  898.         subq.w          #1,D0             ;for DBRA
  899. change_fat1:
  900.         movep.w         1(A0),D1
  901.         move.b          (A0),D1         ;Intel-transformation to 16-bit-FAT
  902.         addq.l          #2,A0
  903.         move.w          D1,(A1)+
  904.         dbra            D0,change_fat1
  905.         rts
  906. change_fat2:
  907.         divu            #3,D0           ;Change 12-bit-FAT
  908. change_fat3:
  909.         movep.w         1(A0),D1
  910.         move.b          (A0),D1         ;Fetch Intel-Word 
  911.         and.w           #$0FFF,D1       ;Bit 12-15 are unimportant
  912.         cmp.w           #$0FF0,D1       ;Number $FF0-$FFF?
  913.         blo.s           change_fat4     ;No! =>
  914.         or.w            #$F000,D1       ;extend sign
  915. change_fat4:
  916.         move.w          D1,(A1)+        ;Mark cluster
  917.         movep.w         2(A0),D1
  918.         move.b          1(A0),D1        ;Fetch Intel-Word 
  919.         lsr.w           #4,D1           ;Bit 0-3 are unimportant
  920.         cmp.w           #$0FF0,D1       ;Number $FF0-$FFF?
  921.         blo.s           change_fat5     ;No! =>
  922.         or.w            #$F000,D1       ;Extend sign
  923. change_fat5:
  924.         move.w          D1,(A1)+        ;Mark cluster 
  925.         addq.l          #3,A0           ;3 Bytes are ready
  926.         dbra            D0,change_fat3  ;already all Triple?
  927.         rts
  928.                 ENDPART
  929. *************************************************
  930. * D0=get_mem(Byte number in D0)                 *
  931. *    requisition memory from the stack.         *
  932. *************************************************
  933.                 PART 'get_mem'
  934. get_mem:
  935.         move.l          A0,-(SP)
  936.         addq.l          #1,D0               ;EVEN
  937.         and.b           #-2,D0
  938.         move.l          stack_pnt(A6),D1    ;old Stack-Pointer
  939.         exg             D0,D1
  940.         add.l           D1,stack_pnt(A6)    ;Place on the stack
  941.         movea.l         start-256+4(PC),A0  ;End of memory
  942.         cmpa.l          stack_pnt(A6),A0    ;Upper limit of memory?
  943.         blo             _exit               ;Yes! => exit =>
  944.         movea.l         (SP)+,A0
  945.         rts
  946.                 ENDPART
  947. *************************************************
  948. * From here: the DATA-Segment                   *
  949. *************************************************
  950.                 DATA
  951.                 IF virus
  952. files_text:
  953.                 DC.B ' Files, ',0
  954. files_text2:
  955.                 DC.B ' altered e.g. new Files.',13,10,0
  956. folders_text:
  957.                 DC.B ' Folder available.'
  958.                 DC.B ' Write to it?',13,10,0
  959. init_text:
  960.                 DC.B 27,'E',27,'e'
  961.                 DC.B 'LVF V1.5 (Link-Virus-Finder)',13,10
  962.                 DC.B '©1989 by Σ-soft,'
  963.                 DC.B ' Markus Fritze',13,10,10,0
  964. error_text:
  965.                 DC.B 'Checksum is incorrect'
  966.                 DC.B ' (accept?)',13,10,0
  967. virus_text:
  968.                 DC.B 7,'File contains '
  969.                 DC.B ' probably ',0
  970. virus1_text:
  971.                 DC.B 'a VCS-Linkvirus!',13,10,7,0
  972. virus2_text:
  973.                 DC.B 'the Milzbrand-Linkvirus!',13,10,7,0
  974. virus_text:
  975.                 DC.B ' possibly contaminated'
  976.                 DC.B ' Files found!',7,13,10,0
  977. new_text:
  978.                 DC.B 'File has been added.',13,10,0
  979. fname:
  980.                 DC.B 'LVF.DAT',0
  981.                 ELSE
  982. files_text:
  983.                 DC.B ' Files with altogether ',0
  984. files_text2:
  985.                 DC.B ' Bytes found.',13,10,0
  986. folders_text:
  987.                 DC.B ' Folders available.'
  988.                 DC.B ' Press a Key.',13,10,0
  989. init_text:
  990.                 DC.B 27,'E',27,'e'
  991.                 DC.B 'FFF V1.5 (Fast-File-Finder)',13,10
  992.                 DC.B '©1989 by Σ-soft, Markus Fritze'
  993.                 DC.B 13,10,10,0
  994.                 ENDC
  995. exit_text:      DC.B 27,'E',27,'f',0
  996. drive_text:     DC.B 'Drive ',0
  997. drive_text2:    DC.B ': (',0
  998. drive_text3:    DC.B ' Bytes free.)',13,10,0
  999.  
  1000. **********************************************
  1001. * From here: the BSS-Segment                 *
  1002. **********************************************
  1003.                 BSS
  1004.                 DS.L 1024           ;4k Stack for recursive search
  1005. own_stack:      DS.L 0
  1006. drive:          DS.W 1              ;actual Drive
  1007. act_bpb:        DS.L 1              ;Pointer: BPB of the actual Drives
  1008. fat_buffer:     DS.L 1              ;Address of the FAT read in
  1009. fat_adr:        DS.L 1              ;Address of the decoded FAT
  1010. virus_count:    DS.W 1              ;Number of Viruses found
  1011. flag:           DS.B 1              ;Bit 0=1: no File output
  1012. ;Bit 1=1: new Program undertaken
  1013.                 EVEN
  1014. path:           DS.B 256            ;Space for the search path
  1015. stack_pnt:       DS.L 1
  1016.                 IF virus
  1017. data_base:      DS.L 1              ;Pointer: File-Data in RAM
  1018. data_buff:      DS.B 24*max_prgs    ;Program-Buffer
  1019. sector_buffer:  DS.B max_sectorsize ;Sector buffer.
  1020.                 ELSE
  1021. search_mask:    DS.B 12             ;Search mask (Joker)
  1022. search_chars:   DS.B 12             ;Search characters
  1023.                 ENDC
  1024. stack:          DS.L 0              ;free memory to here
  1025.                 END
  1026.