home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcresour / 1988_08 / search.asm < prev    next >
Assembly Source File  |  1988-04-18  |  7KB  |  259 lines

  1. comment |
  2.    This program will search for all files matching a given template
  3.    (file name or file name with wild cards) on the default drive.
  4.    Calling sequence:
  5.        SEARCH filename
  6.  
  7.    Written for MASM 5.0
  8.  
  9.    Save as  SEARCH.ASM
  10.    Compile: MASM SEARCH;
  11.            LINK SEARCH;  (ignore stack segment warning)
  12.         EXE2BIN SEARCH SEARCH.COM
  13.     |
  14.  
  15. rpush    macro    x            ;;Push multiple registers
  16.     irp    y,<x>
  17.     push    y
  18.     endm
  19.     endm
  20.  
  21. rpop    macro    x            ;;Pop multiple registers
  22.     irp    y,<x>
  23.     pop    y
  24.     endm
  25.     endm
  26.  
  27. DOScall    macro    x            ;;Call MS-DOS
  28.     mov    ah,x
  29.     int    21h
  30.     endm
  31.  
  32. DTA    struc                ;Disk Transfer area structure
  33.     db 15h dup (?)            ;21 reserved bytes
  34. atr    db    ?            ;1-byte attribute
  35. time    dw    ?            ;2-byte file time
  36. date    dw    ?            ;2-byte file date
  37. fsize    dd    ?            ;4-byte file size
  38. fname    db 0dh dup (?)            ;13-byte file name
  39. DTA    ends
  40.     
  41. DTAsize    equ    2ch            ;Size of one DTA
  42.  
  43. DIR    struc                ;Directory name structure
  44. drive    db    ?            ;Drive letter
  45.     db    ":\"            ;Separator
  46. direc    db 40h dup (?)            ;Room for full subdir path
  47.     db    0            ;Terminator
  48. DIR    ends
  49.  
  50.  
  51. PROG    segment
  52.     assume cs:PROG, ds:PROG, es:PROG, ss:PROG
  53.  
  54.  
  55.     org    100h
  56. start:    jmp    begin
  57.  
  58.         ;**********
  59.         ;   Program data
  60.         ;**********
  61.  
  62. curdr    DIR    <>            ;Current drive
  63. startdr    DIR    <>            ;Starting directory
  64.  
  65. dirattr    equ    10h            ;Subdirectory attribute
  66. filattr    equ    00h            ;Find "normal" files only
  67.  
  68. filname    db    12 dup (?),0
  69. dirname    db    "*.*",0
  70. parent    db    "..",0
  71.  
  72. cr    equ    13
  73. lf    equ    10
  74. tab    equ    9
  75. crlf    db    cr,lf,'$'
  76.  
  77. noroom    db    cr,lf,"Subdirectories nested too deeply."
  78.     db    cr,lf,"This program is out of room.$"
  79.  
  80.  
  81. begin:    cld                ;Be sure direction flag is reset
  82.     call    get_start        ;Get starting subdirectory
  83.     call    get_filenam        ;Get user's request
  84.     mov    ah,startdr.drive    ;Get current drive
  85.     mov    curdr.drive,ah        ;Save it
  86.     mov    curdr.direc,0        ;And move to top of drive
  87.     lea    dx,curdr.drive        ;DS:DX ==> directory name
  88.     DOScall    3bh            ;CHDIR to root directory
  89.     call    searchdir        ;Search the root directory
  90.     lea    dx,startdr.drive    ;DS:DX ==> original path
  91.     DOScall    3bh            ;CHDIR to original directory
  92.     mov    al,0            ;Report success to DOS
  93.     DOScall    4ch            ;Exit program
  94.  
  95. get_start    proc
  96.     rpush    <si,dx>
  97.     DOScall    19h            ;Get current drive
  98.     add    al,'A'            ;Make it ASCII
  99.     mov    startdr.drive,al    ;Save it
  100.     lea    si,startdr.direc    ;DS:SI ==> buffer
  101.     mov    dl,0            ;Select default drive
  102.     DOScall    47h            ;Get current directory
  103.     rpop    <dx,si>
  104.     ret
  105. get_start    endp            
  106.     
  107. get_filenam    proc
  108.     rpush    <di,si,cx>
  109.     lea    di,filname        ;ES:DI ==> storage area
  110.     mov    si,5dh            ;DS:SI ==> Formatted parm #1
  111.     cmp    byte ptr [si],' '    ;Anything there?
  112.     jnz    gp0            ;Yes -- go
  113.     mov    al,0ffh            ;Else report an error to caller
  114.     DOScall    4ch            ;Exit program
  115.  
  116. gp0:    mov    cx,8            ;Filename length
  117. gp1:    lodsb                ;Get a byte
  118.     cmp    al,' '            ;Is it a space?
  119.     je    gp2            ;Yes -- go
  120.     stosb                ;Else move it
  121. gp2:    loop    gp1            ;Repeat for full name
  122.     mov    ax,'.'            ;Now save separator
  123.     stosb
  124.     mov    cx,3            ;Length of extension
  125. gp3:    lodsb                ;Get a byte
  126.     cmp    al,' '            ;Is it a space?
  127.     je    gp4            ;Yes -- go
  128.     stosb                ;Else save it
  129.     loop    gp3            ;Finish file extension
  130. gp4:    mov    al,0            ;Terminate string
  131.     stosb
  132.     rpop    <cx,si,di>
  133.     ret
  134. get_filenam    endp
  135.  
  136. our_dta    equ    sp            ;Shorthand DTA address
  137.  
  138. searchdir    proc            ;Search the current directory
  139.     push    bp            ;Save previous stack frame
  140.     mov    bp,sp            ;Set our stack frame
  141.     mov    ax,sp            ;Get SP for testing
  142.     sub    ax,endloc        ;Room for another DTA?
  143.     jnc    srd1            ;Yes -- start routine
  144.     lea    dx,noroom        ;Else point to message
  145.     DOScall    9            ;Display a string
  146.     mov    al,0ffh            ;Report an error
  147.     DOScall    4ch            ;Exit program
  148.  
  149. srd1:    sub    sp,DTAsize        ;Make room for DTA
  150. ;**********
  151. ; Find matching filenames
  152. ;**********
  153.     mov    bx,our_dta        ;Get address for ourselves
  154.     push    our_dta            ;Save address to pass to subs
  155.     mov    dx,bx            ;DTA address to dx
  156.     DOScall    1ah            ;Set DTA
  157.     lea    dx,filname        ;DS:DX ==> filename
  158.     mov    cx,filattr        ;Attribute to search for
  159.     DOScall    4eh            ;Find first file
  160.     jc    srd3            ;Nothing found -- go
  161.     call    print_dir        ;Else print the subdir name
  162. srd2:    call    print_fname        ;Then print the file name
  163.     DOScall    4fh            ;Find next file
  164.     jnc    srd2            ;Loop back if found
  165. ;**********
  166. ; Find subdirectories
  167. ;**********
  168. srd3:    lea    dx,dirname        ;DS:DX ==> "*.*"
  169.     mov    cx,dirattr        ;Include subdirs in search
  170.     DOScall    4eh            ;Find first file
  171. srd4:    jc    srd6            ;Go if nothing found
  172.     mov    al,[bx + DTA.atr]    ;Test file's attribute 
  173.     cmp    al,dirattr        ;Is it a directory?
  174.     jne    srd5            ;No -- go
  175.     mov    al,[bx + DTA.fname]    ;Look at file name
  176.     cmp    al,'.'            ;Does it start with '.'?
  177.     je    srd5            ;Yes -- go
  178.     push    bx            ;Save our DTA address
  179.     call    login            ;Log in to subdir
  180.     call    searchdir        ;And search it
  181.     call    logout            ;Then log out of subdir
  182.     pop    bx            ;Recover DTA address
  183.     mov    dx,bx            ;Get original DTA address
  184.     DOScall    1ah            ;Set our DTA again
  185. srd5:    DOScall    4fh            ;Find next subdirectory
  186.     jmp    srd4            ;Loop back
  187.  
  188. srd6:    mov    sp,bp            ;Reset the stack
  189.     pop    bp            ;Recover former stack frame
  190.     ret
  191. searchdir    endp
  192.  
  193. print_dir    proc
  194.     rpush    <si,dx>
  195.     lea    si,curdr.direc        ;DS:SI ==> buffer area
  196.     mov    dl,0            ;Select current drive
  197.     DOScall    47h            ;Get default directory
  198.     lea    si,curdr.drive        ;DS:SI ==> full path name
  199.     call    print_az        ;Print ASCIIZ string
  200.     rpop    <dx,si>
  201.     ret
  202. print_dir    endp
  203.  
  204. this_DTA equ    [bp+4]            ;Stack location for DTA addr.
  205.  
  206. print_fname    proc
  207.     push    bp            ;Save frame pointer
  208.     mov    bp,sp            ;Save the stack pointer
  209.     rpush    <si,dx>
  210.     mov    si,this_DTA        ;DS:SI ==> DTA in use
  211.     add    si,DTA.fname        ;DS:SI ==> current filename
  212.     mov    dl,tab            ;First print a tab
  213.     DOScall    2            ;Print a character
  214.     call    print_az        ;Print ASCIIZ string
  215.     rpop    <dx,si,bp>        ;Clear the stack
  216.     ret
  217. print_fname    endp
  218.  
  219. print_az    proc            ;Print ASCIIZ string at SI
  220.     rpush    <bx,cx,dx,si>        ;Save SI last
  221.     sub    cx,cx            ;Start with count of 0
  222. pa1:    lodsb                ;Get a byte
  223.     cmp    al,0            ;At the end?
  224.     jz    pa2            ;Yes -- go
  225.     inc    cx            ;Else count it
  226.     jmp    pa1            ;And repeat
  227. pa2:    pop    dx            ;Recover original addr.
  228.     mov    bx,1            ;STDOUT handle
  229.     DOScall    40h            ;Write to file/handle
  230.     lea    dx,crlf            ;Terminate line
  231.     DOScall    9            ;Print a string
  232.     rpop    <dx,cx,bx>        ;Clear the stack
  233.     ret
  234. print_az    endp
  235.  
  236. login        proc
  237.     push    bp            ;Save the stack frame
  238.     mov    bp,sp            ;And the stack pointer
  239.     push    dx            ;Save caller's DX
  240.     mov    dx,this_DTA        ;Point to current DTA
  241.     add    dx,DTA.fname        ;DS:DX ==> directory name
  242.     DOScall    3bh            ;CHDIR to new directory
  243.     rpop    <dx,bp>            ;Clear the stack
  244.     ret
  245. login        endp
  246.  
  247. logout        proc
  248.     push    dx            ;Save caller's DX
  249.     lea    dx,parent        ;DS:DX ==> '..'
  250.     DOScall    3bh            ;CHDIR to parent directory
  251.     pop    dx            ;Clear the stack
  252.     ret
  253. logout        endp
  254. endloc    dw    $ + 100h + DTAsize    ;Leave room for normal stack
  255.                     ;  and one DTA
  256. prog    ends
  257.     end    start
  258.  
  259.