;-----------------------------------------
; Universal Dos Routine (UDR)
;
; (c) 09.94 by Capella/Escape
;
; NOT FOR RELEASE !!!
;-----------------------------------------
; routine searching for max. 200 names
; needs 3531 Bytes of Data-segment
;-----------------------------------------

ideal
model large
p386n
stack 256

assume cs:coding

segment coding

max_files  = 200
max_paths  = 10                

anti_virus      db "ESCAPE"
                
start:          mov ax,data1
                mov ds,ax
                assume ds:data1

                mov ax,0003h
                int 10h
                
                mov eax,[cs:0000]        ;checks if program is changed
                cmp eax,"ACSE"
                je virusc1
virusc2:        mov ah,09h
                mov dx,offset virus_mess
                int 21h
                jmp exit
virusc1:        mov ax,[cs:0004]
                cmp ax,"PE"
                je virusc2
                
                mov dx,offset dir_puffer   ;set pointer to new DTA-puffer
                mov ax,1a00h
                int 21h
                
                call ask_drive
                
                xor dl,dl
                mov di,offset path_sign
                call ask_path
                
                mov dx,offset search_name
                call ask_subpaths
                
                mov dx,offset search_name
                call ask_files
                
                call display_dir


warte:          in al,60h
                cmp al,01h
                jne warte

exit:           mov ax,4c01h
                int 21h
;-----------------------------------------
; ASK_DRIVE
;
; OUT:  AL : 0= Drive A
;            1= Drive B
;            2= Drive C
;            3= Drive D
;            4= Drive E
;-----------------------------------------
ask_drive:      mov ax,1900h
                int 21h

                cmp al,0
                jne ad1
                mov [ds:drive_no],"A"
                ret
ad1:            cmp al,1
                jne ad2
                mov [ds:drive_no],"B"
                ret
ad2:            cmp al,2
                jne ad3
                mov [ds:drive_no],"C"
                ret
ad3:            cmp al,3
                jne ad4
                mov [ds:drive_no],"D"
                ret
ad4:            cmp al,4
                jne ad5
                mov [ds:drive_no],"E"
                ret
ad5:            mov [ds:drive_no],"?"
                ret
;-----------------------------------------
; ASK_PATH
;
; IN:   DS:DI = FAR-Pointer to Puffer
;       DL    = Drive : 0= current Drive
;                       1= Drive A
;                       2= Drive B
;                       3= Drive C
;                       4= Drive D
;                       5= Drive E
;
; OUT:  Carry-Flag= 1 then AX= Errorcode
;-----------------------------------------
ask_path:       mov ax,4700h
                int 21h
                jnc ap1
                mov [ds:error_code],ax
ap1:            ret
;-----------------------------------------
; ASK_FILES
;
; IN:  DS:DX = FAR-Pointer of Filename to search for
;      
; OUT: Carry-Flag=1 then AX= Errorcode
;-----------------------------------------
ask_files:      xor cx,cx               ;attribute-code for normal files
                xor bp,bp               ;file-pointer to zero
                mov di,offset file_size
                mov si,offset dir_puffer
                xor ax,ax
                mov cx, max_files*13*4/2  ;clear file_size
af3:            mov [ds:di],ax
                add di,02h
                loop af3
                mov di,offset file_size
                mov ax,4e00h
                int 21h
                jnc af1
                mov [ds:error_code],ax
af2:            mov [ds:real_files],bp
                ret
af1:            call get_para
                inc bp
                cmp bp,max_files
                jae af2
                mov ax,4f00h
                int 21h
                jnc af1
                mov [ds:error_code],ax
                mov [ds:real_files],bp
                ret
                
get_para:       push si           ;get filename
                push di                          
                xor cx,cx
af5:            mov al,[ds:si+30]
                cmp al,0
                je af4
                mov [ds:di],al
                inc si
                inc di
                inc cx
                cmp cx,13
                je af4
                jmp af5
af4:            pop di            ;get filesize
                pop si
                add di,13
                mov eax,[ds:si+26]
                mov [ds:di],eax
                add di,4
                ret
;-----------------------------------------
; ASK_SUBPATHS
;
; OUT: AL=0 -no sub_paths found
;         1 -sub_paths found
;      CX= amount of sub_paths
;-----------------------------------------
ask_subpaths:   mov cx,10h          ;attribute-code for sub_paths
                xor bp,bp
                mov si,offset dir_puffer
                mov di,offset sub_paths
                xor ax,ax
                push di
                push cx
                mov cx,max_paths*13
asp3:           mov [ds:di],al
                inc di
                loop asp3
                pop cx
                pop di
                mov ax,4e00h
                int 21h
                jnc asp1
                mov [ds:error_code],ax
                mov [ds:real_paths],bp
                ret
asp1:           call get_subpara
                cmp bp,max_paths
                jb asp2
                mov [ds:real_paths],bp
                ret
asp2:           mov ax,4f00h
                int 21h
                jnc asp1
                mov [ds:error_code],ax
                mov [ds:real_paths],bp
                ret

get_subpara:    push si
                push di
                xor cx,cx
                cmp [byte ds:si+21],10h
                je gsp2
                pop di
                pop si
                ret
gsp2:           mov al,[ds:si+30]
                cmp al,0
                je gsp1
                mov [ds:di],al
                inc si
                inc di
                jmp gsp2
gsp1:           pop di
                pop si
                add di,13
                inc bp
                ret
;-----------------------------------------
; DISPLAY_DIR
;
; Simple display-routine to test out the
; functions of this module
;-----------------------------------------
display_dir:    mov ax,0b800h
                mov es,ax
                assume es:0b800h
                xor bx,bx
                xor bp,bp
                xor di,di
                mov ah,04h
                mov si,offset file_size

dd2:            push si
                push di

                mov cx,13
dd1:            mov al,[ds:si]
                mov [es:di],ax
                inc si
                add di,02
                loop dd1

                pop di
                pop si
                add si,13+4
                add di,160

                inc bp
                cmp bp,[ds:real_files]
                je dd3
                
                inc bx
                cmp bx,80
                jne dd2

dd3:            mov si,offset sub_paths
                mov di,20*2
                xor bx,bx
                mov bp,[ds:real_paths]
                
dd5:            push di
                mov cx,13
dd4:            mov al,[ds:si]
                mov [es:di],al
                inc si
                add di,02h
                loop dd4
                pop di
                
                add di,160

                inc bx
                cmp bx,bp
                jne dd5
                ret
                


ends coding


segment  data1

virus_mess  db 13,10,"- ATTENTION !!! ORIGINAL FILE IS CHANGED....MAYBE VIRUS !!!"
            db 13,10,"  PLEASE CHECK YOUR SYSTEM !!!!!",13,10,"$"

dir_puffer  db 43 dup (0)
error_code  dw 00
search_name db "*.*",0
real_files  dw 00
real_paths  dw 00
drive_no    db 0
path_sign   db 80 dup (0)
sub_paths   db max_paths*13 dup (0)
file_size   db max_files*13 dup (0)
            db max_files*4 dup (0)

ends  data1

end start

