geller@rlgvax.UUCP (David Geller) (02/15/84)
I'm an IBM PC DOS 2.0 / Lattice "C" (ver 2.0-d) user and I would like to know how to get a directory listing of both root and sub- directories, preferably through Lattice/Microsoft "C". It would help if I knew, without dissassembling, how DIR and TREE worked. I suspect that they both use the DOS interupts to search for and continue a directory search, however I'm not at all sure. I would appreciate any help that you could offer. I'll post a follow-up article to this query as soon as I receive some help. Thanks in advance, {seismo}!rlgvax!geller David Geller Computer Consoles, Inc. Office Systems Group 1760 Reston Avenue Reston, VA 22090 703-471-6860
jph@whuxle.UUCP (02/23/84)
#R:rlgvax:-171200:whuxle:22700016:000:6083 whuxle!jph Feb 18 21:35:00 1984 Here is the source code for WHEREIS which takes a file name of pattern (e.g., *.BAS) as an argument and finds where it is in the file system by starting at the root and working it way down through all the sub-directories. You might take this algorithm and use it in your function for C. I obtained this from a BBS. ============================================ title WHEREIS page 62,132 cgroup group code_seg,data_seg assume cs:cgroup,ds:cgroup ;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 data_seg segment public star_name db '*.*',0 path_name db '\',0 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 starts at the end of whereis data_seg ends ; 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 ; code_seg segment org 100h whereis proc near mov si, 82h ;start of command line mov di, offset cgroup:file_name wh10: lodsb ;get first char cmp al, 0dh je wh20 ;if carriage return stosb jmp wh10 ;Loop -- wh20: xor al,al ;store zero at end stosb mov di, offset cgroup:path_name xor al, al cld mov cx, 64 repnz scasb mov bx,di dec bx ;ds:bx points to end of path_name mov dx, 0 call search_directory int 20h whereis 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 sd20 ;If no match -- call write_matched_name sd10: call get_next_match jc sd20 call write_matched_name jmp sd10 ;Loop -- sd20: pop dx push dx call build_star_name call get_first_match jc sd50 ;If no match -- mov si,dx test [si].attribute,10h jnz sd40 ;If directory entry -- sd30: call get_next_match jc sd50 ;If no more entries -- test [si].attribute,10h jz sd30 ;If not a directory -- sd40: cmp [si].name_found,'.' je sd30 ;If it's . or .. call search_sub_directory ;search sub directory push ax mov ah,1ah int 21h pop ax jmp sd30 sd50: 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 ss10: lodsb stosb or al,al jnz ss10 mov bx,di std stosb mov al,'\' stosb call search_directory pop bx mov byte ptr [bx], 0 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 cgroup:path_name mov al,[bx] mov byte ptr [bx],0 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 cgroup:file_name call build pop si ret build_name endp build_star_name proc near push si mov si, offset cgroup: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 bd10: lodsb stosb or al,al jnz bd10 ;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,0 ja gf10 ;go allocate space -- mov dx, offset cgroup:disk_transfer_areas-type dta gf10: add dx,type dta mov cx,10h mov ah,1ah int 21h push dx mov dx, offset cgroup:path_name mov ah,4eh ;call for find first match int 21h pop dx pop cx ret get_first_match endp ; This procedure is much line 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 cgroup:path_name mov cx,10h mov ah,4fh int 21h 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,02 mov dl,0ah int 21h mov dl,0dh int 21h 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,2 lodsb ws10: mov dl,al int 21h lodsb or al,al jnz ws10 pop si pop dx pop ax ret write_string endp code_seg ends end whereis