home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
dirutl
/
whereis.asm
< prev
next >
Wrap
Assembly Source File
|
1992-09-08
|
11KB
|
413 lines
title WHEREIS
page 55,131
;********************************************************
;* *
;* WHEREIS.ASM 24FEB84 *
;* *
;********************************************************
; Modified 10/22/85 by Tom Brengle (BRENGLE%LLL@LLL-MFE)
; If no extension is included in the command line filespec,
; WHEREIS now acts the same as the DOS DIR command, that is
;
; WHEREIS file
;
; performs the same search as if
;
; WHEREIS file.*
;
; had been entered. WHEREIS can still look for files
; with only null extensions by using
;
; WHEREIS file.
whereis segment public
assume cs:whereis,ds:whereis
;equates
COMMAND_LINE EQU 80H + 2
NULL EQU 00H
CR EQU 0DH
LF EQU 0AH
MAX_SCAN_LEN EQU 64
TERMINATE EQU 20H
DIRECTORY EQU 10H
DOT EQU '.'
STAR EQU '*'
PRINT_CHAR EQU 02H
SET_DTA EQU 1AH
SEARCH_FIRST EQU 4EH
SEARCH_NEXT EQU 4FH
DOS_CALL EQU 21H
PATH_SEPARATOR EQU '\'
;macros
CLEAR macro reg
xor reg,reg
endm
;this is the format for the dos data transfer area used when dos 2.0
;searches for file match in directories
dta struc
reserved db 21 dup (?)
attribute db ?
time dw ?
date dw ?
size dd ?
name_found db 13 dup (?)
dta ends
org 100h
main proc far
; this is the main program that sets up the initial conditions for
; search_directory which in turn, does a recursive search.
; reads: path_name
; writes: file_name
; calls: search_directory
;
mainline proc near
start:
mov bp, 0 ;Clear DOT_FLAG.
mov si, COMMAND_LINE ;start of command line
mov di, offset file_name
get_search_name:
lodsb ;get first char
cmp al, DOT ;Is it a dot?
jne check_CR ;No, then check for carriage return.
mov bp, 1 ;Yes, then set DOT_FLAG.
stosb
jmp get_search_name ;Loop --
check_CR:
cmp al, CR
je done_reading_name ;if carriage return
stosb
jmp get_search_name ;Loop --
done_reading_name:
cmp bp, 1 ;Was a dot seen?
je terminate_name ;Yes, go finish name processing.
mov al, DOT ;No, then append ".*" to file spec.
stosb
mov al, STAR
stosb
terminate_name:
CLEAR al ;store zero at end
stosb
mov di, offset path_name
CLEAR al
cld
mov cx, MAX_SCAN_LEN
repnz scasb
mov bx,di
dec bx ;ds:bx points to end of path_name
mov dx,NULL
call search_directory
int TERMINATE
mainline endp
; this procedure searches all the files in the current directory
; looking for a match. It also prints the full name for each match
;
; ds:bx pointer to end of current path name
; ds:dx old disk transfer area (dta)
;
; reads: disk transfer area (dta)
; writes: disk transfer area (dta)
; calls build_name, get_first_Match
; write_matched_name, get_next_match
; build_star_name, search_sub_directory
;
search_directory proc near
push si
push dx
call build_name
call get_first_match
jc no_match ;If no match --
call write_matched_name
find_next_file:
call get_next_match
jc no_match
call write_matched_name
jmp find_next_file ;Loop --
no_match:
pop dx
push dx
call build_star_name
call get_first_match
jc no_more_matches ;If no match --
mov si,dx
test [si].attribute,DIRECTORY
jnz is_directory ;If directory entry --
find_next_directory:
call get_next_match
jc no_more_matches ;If no more entries --
test [si].attribute,DIRECTORY
jz find_next_directory ;If not a directory --
is_directory:
cmp [si].name_found,DOT
je find_next_directory ;If it's . or ..
call search_sub_directory ;search sub directory
push ax
mov ah,SET_DTA
int DOS_CALL
pop ax
jmp find_next_directory
no_more_matches:
pop dx
pop si
ret
search_directory endp
page
; This procedure searches the sub directory who's name is in dta
;
; ds:bx end of the current pathname
; ds:[dx].name_found name of subdirectory for search
;
; reads: path_name
; writes: path_name
; calls: search_directory
;
search_sub_directory proc near
push di
push si
push ax
push bx
cld
mov si, dx
add si, offset name_found
mov di,bx
copy_loop:
lodsb
stosb
or al,al
jnz copy_loop
mov bx,di
std
stosb
mov al,PATH_SEPARATOR
stosb
call search_directory
pop bx
mov byte ptr [bx],NULL
pop ax
pop si
pop di
ret
search_sub_directory endp
page
; This procedure prints the matched name after the path name
;
; ds:dx pointer to current disk transfer area
;
; reads: path_name, name_found (in dta)
; writes: write_string, send_crlf
;
write_matched_name proc near
push ax
push dx
mov dx,offset path_name
mov al,[bx]
mov byte ptr [bx],NULL
call write_string
mov [bx],al
pop dx
push dx
add dx, offset name_found
call write_string
call send_crlf
pop dx
pop ax
ret
write_matched_name endp
; This procedure builds an absolute search name from path_name
; followed by file_name
;
; reads: file_name
; calls: build (to build the name)
;
build_name proc near
push si
mov si, offset file_name
call build
pop si
ret
build_name endp
build_star_name proc near
push si
mov si, offset star_name
call build
pop si
ret
build_star_name endp
page
; This procedure appends the string at ds:si to path_name in
; path_name. It knows where the path name ends from knowing
; how long path_name is.
;
; ds:si name of file
; ds:bx end of path_name
;
; reads: ds:si
; writes: path_name
;
build proc near
push ax
push di
mov di,bx
cld
copy_name:
lodsb
stosb
or al,al
jnz copy_name ;If not end of string yet --
pop di
pop ax
ret
build endp
; This procedure find the first match between the name given by
; ds:dx and the directory entries found in the directory path_name
;
; ds:dx pointer to current disk transfer area
;
; returns:
; cf 0 a match was found
; 1 no match found
; ax error code returned
; 2 file not found
; 18 no more files
; ds:dx pointer to new disk transfer area
;
; reads: path_name
; writes: disk_transfer_areas
;
get_first_match proc near
push cx
cmp dx,NULL
ja allocate ;go allocate space --
mov dx, offset disk_transfer_areas-type dta
allocate:
add dx,type dta
mov cx,DIRECTORY
mov ah,SET_DTA
int DOS_CALL
push dx
mov dx, offset path_name
mov ah,SEARCH_FIRST ;call for find first match
int DOS_CALL
pop dx
pop cx
ret
get_first_match endp
; This procedure is much like get_first_match
;
; returns:
; cf 0 a match was found
; 1 no match found
; ax error code returned
; 2 file not found
; 18 no more files
;
; reads: path_name
; writes: disk_transfer_areas
;
get_next_match proc near
push cx
push dx
mov dx, offset path_name
mov cx,DIRECTORY
mov ah,SEARCH_NEXT
int DOS_CALL
pop dx
pop cx
ret
get_next_match endp
; This procedure sends a crlf pair of characters to the screen
;
send_crlf proc near
push ax
push dx
mov ah,PRINT_CHAR
mov dl,CR
int DOS_CALL
mov dl,LF
int DOS_CALL
pop dx
pop ax
ret
send_crlf endp
; This procedure writes the asciiz string at
; ds:dx address of asciiz string
;
write_string proc near
push ax
push dx
push si
cld
mov si,dx
mov ah,PRINT_CHAR
lodsb
write_string_loop:
mov dl,al
int DOS_CALL
lodsb
or al,al
jnz write_string_loop
pop si
pop dx
pop ax
ret
write_string endp
; This is the data storage area and must be the last thing
; in the program.
;
star_name db '*.*',NULL
path_name db PATH_SEPARATOR,NULL
db 80 dup (0) ;space for 64 char pathname and
;13 char filename
file_name db 13 dup (0) ;save room for full dos filename
disk_transfer_areas label byte ;this must start at the end of whereis
main endp
whereis ends
end start