[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 5, May 1998 file 015
Два способа обхода дерева каталогов
by All
=== Cut ===............................................................Метод 1
;
; Рекурсивный поиск файлов.
; (c) Ak Kort [SOS group]
; Microsoft Assembler 6.0
;
.model tiny
.486
.code
.startup
org 100h
jmp beg
msk byte '*.exe',0 ; Какие файлы искать.
pth byte '\',0 ; Где искать.
dsk byte 2 ; на каком диске (сейчас - С)
all byte '*.*',0 ; Чтобы входить во все подкаталоги
old byte '..',0 ; предыдущий каталог
oldpath byte 64 dup (0) ; старый каталог
curpath byte 64 dup (0) ; текущий каталог
beg:
mov ah,19h
int 21h
mov ah,0Eh
push ax
mov dl,dsk
int 21h
mov ah,47h
cwd
lea si,oldpath
push si
int 21h
lea dx,pth
call Recurse
pop dx
mov ah,3Bh
int 21h
pop ax
mov dl,al
int 21h
retn
Recurse:
mov ah,3Bh ; переходим в новый каталог
int 21h
sub sp,44 ; создаем локальную DTA
mov dx,sp ; всего может быть не более 31 подкаталога => всего
mov si,dx ; может потребоваться (44+4)*31=1488 байт стека
add si,1Eh ; не так уж и много
mov ah,1Ah
int 21h
lea dx,msk ; поиск файлов
xor cx,cx
mov ah,4Eh
int 21h
jc @1
@2: call PrintName ; нашли!
mov ah,4Fh
int 21h
jnc @2
@1:
mov cx,16 ; поиск всех каталогов
lea dx,all
mov ah,4Eh
int 21h
jc @3
@5:
test byte ptr [si-9],16 ; подлая ms-dos вместе с каталогами выдает
; и файлы - будем отсекать
jz @4
cmp word ptr [si],'.' ; корневая директория
jz @4
cmp word ptr [si],'..' ; надкаталог
jz @4
push si
mov dx,si
call Recurse ; рекурсивный вызов
lea dx,old ; выодим из подкаталога
mov ah,3Bh
int 21h
pop si
lea dx,[si-1Eh] ; назначаем старую dta
mov ah,1Ah
int 21h
@4:
mov ah,4Fh
int 21h
jnc @5
@3:
add sp,44 ; удалаяем локальную dta
retn
PrintName:
push si
mov al,dsk
add al,'A'
int 29h ; int 29h - fast put char
mov al,':'
int 29h
mov al,'\'
int 29h
lea dx,curpath
mov ah,47h
mov si,dx
cwd
int 21h
call PrintStr
mov al,'\' ; для файлов в корневухе напечатается два слеша,
int 29h ; что в принципе не страшно
pop si
call PrintStr
mov al,13
int 29h
mov al,10
int 29h
retn
PrintStr:
push si
@6: lodsb
or al,al
jz @7
int 29h
jmp @6
@7:
pop si
retn
end
=== Cut ===
=== Cut ===............................................................Метод 2
;
; Нерекурсивный поиск файлов.
; (c) Constantin Sergeev 2:5085/21.13
; Microsoft Assembler 6.0
;
Hакалякал прогу.... Виснет зараза на некоторых машинах ...
Посмотрите, может найдете багу ...
Title Qdir
Model Small
CodeSeg
.386
Org 0100h
Dta_Str_Attr Equ Offset Dta + 15h
Dta_Str_DaTi Equ Offset Dta + 16h
Dta_Str_Size Equ Offset Dta + 1ah
Dta_Str_Name Equ Offset Dta + 1eh
Last_Char_Is Equ Offset Tmp_Mask+12
Addr1_Stop Equ Offset Stop_Byte
Addr2_Stop Equ Offset Stop_Byte+1
Stack_Locate Equ Offset Stack_Prog+Size_Stack
Begin:
;Установим Видеомоду
Mov Ax,3
Int 10h
;Подготовим регистры
Push Cs
Pop Ds
Push Cs
Pop Es
Cli
;Создадим стэк
Push Cs
Pop Ss
Mov Ax,Stack_Locate
Mov Sp,Ax
Sti
; Занесем адресс запуска
Lea Ax,Init
Push Cs
Push Ax
Retf
Exit_Here:
Int 20h
Scan_DDT:
;Процедура находит конец пути
Cld
Lea Di,Way2Found
Xor Al,Al
Mov Cx,72
Repne Scasb
Ret
Modi_DDT:
;Процедура сохраняет \*.*0х0
Dec Di
Mov Ax,'*\'
Stosw
Mov Ax,'*.'
Stosw
Sub Ax,Ax
Stosw
Ret
Init Equ $
; 1.2.1) Устанавливаем DTA
Mov Ah,1ah
Lea Dx,Dta
Int 21h
; 1.2.2) Процедура обхода дерева и нахождения
;Установим каталог и найдем 1й файл
Change_Path:
Mov Ah,4eh
Mov Cx,31-8
Lea Dx,Way2Found
Int 21h
Jc Exit_Here
Found_Next:
;Это каталог ?
Test Byte Ptr Dta_Str_Attr,16
Je Is_Not_Dir
;е поганцевые точки ?
Cmp Byte Ptr [Dta_Str_Name],'.'
Je Is_Not_Print
;Сформируем новый путь
Call Scan_DDT
Sub Di,4
Mov Si,Dta_Str_Name
;Допишем его в конец текущего
Cont_Append:
Lodsb
Stosb
Or Al,Al
Jne Cont_Append
Store_Chars:
Call Modi_DDT
Jmp Change_Path
Is_Not_Dir:
;Печатаем найденное
Call Print_Name
Is_Not_Print:
;Ищем следующие вхождения
Mov Ah,4fh
Int 21h
Jnc Found_Next
;Проверим на не корневой каталог
Scan_Lite:
;Сдвинемся вверх на 1 уровень
Call Scan_DDT
;Сохраним ммя каталога во временной переменной
Sub Di,2
Mov Al,5ch
;Тута выделяем имя каталога
Std
Repne Scasb
Repne Scasb
Cld
Cmp Di,Addr1_Stop
Je Exit_Here
Cmp Di,Addr2_Stop
Je Exit_Here
Add Di,2
Push Di
Push Cx
Mov Cx,12
;Сохраняем и заодно обнуляем хвосты
Lea Si,Tmp_Mask
Cont_Store:
Mov Al,Byte Ptr [Di]
Cmp Al,'\'
Je Break_Store
Inc Di
Jmp No_Way_Store
Break_Store:
Mov Al,0
No_Way_Store:
Mov Byte Ptr [Si],Al
Inc Si
Loop Cont_Store
Pop Cx
Pop Di
Call Modi_DDT
;Повторный поиск (начнем с корня)
Mov Ah,4eh
Mov Cx,31-8
Lea Dx,Way2Found
Int 21h
Jc Scan_Lite
Found_Next_Mach:
Mov Ah,4fh
Int 21h
;ашли. о толи ?
Mov Di,Dta_Str_Name
Push Di
Mov Cx,12
Mov Al,0
Repnz Scasb
Rep Stosb
Lea SI,Tmp_Mask
Pop Di
Cld
Mov Cx,12
Repe Cmpsb
;Да ! Продолжим далее ...
Je Is_Not_Print
Jmp Found_Next_Mach
; Чего-нить печатаем.
Print_Name:
Pusha
Lea Bx,Way2Found
Mov Ah,2
Cont_Print01:
Mov Dl,Byte Ptr [Bx]
Inc Bx
Cmp Byte Ptr [Bx+2],0
Jz Term_Print01
Int 21h
Jmp Cont_Print01
Term_Print01:
Mov Bx,Dta_Str_Name
Cont_Print:
Mov Dl,Byte Ptr [Bx]
Inc Bx
Or Dl,Dl
Jz Term_Print
Int 21h
Jmp Cont_Print
Term_Print:
Mov Dl,13
Int 21h
Mov Dl,10
Int 21h
Popa
Ret
;Служебные метки
Label_Presence Db 'CrCt'
Label_Version Db 0,2
;Красный флаг для сканера
Stop_Byte Db '\\'
;Здесь хранится путь к файликам
Way2Found Db 'C:\*.*',0
Db 73 Dup (0)
;А здесь - ДТА
Dta Db 43 Dup (0)
;Тута лежит имя для поиска в корне дерева
Tmp_Mask Db 12 Dup (0)
Db 0
;А это стэк.
Stack_Prog Db 256 Dup (0)
Size_Stack Equ $-Stack_Prog
Ends
End Begin
=== Cut ===