Seeking a method to "read" a DOS directory
James E. Prior
jep at oink.UUCP
Sat Mar 26 10:42:28 AEST 1988
In article <1001 at mcgill-vision.UUCP> mouse at mcgill-vision.UUCP (der Mouse) writes:
>In article <902 at cblpe.ATT.COM>, jrm at cblpe.ATT.COM (John Miller) writes:
>> I would like obtain a list of files that are in a DOS directory using
>> Microsoft 'C', version 4 or 5.
Sample code is included further down in this article.
I don't remember whether it was for Turbo C or usoft C. It's very
similar either way.
>> The best method I know of so far [...] is to use a DOS interrupt
>> function to gain information about the FAT. [and then read the disk
>> to find the directory]
>
>One of the DOS interrupts expands a wildcard name. Tell it to expand
>*.* and you should get a list of everything. (Actually, one entry
>tells it "get the first name matching this" and another says "get the
>next name matching the last thing I told you to look for", as I
>recall.) Unfortunately, the match routine is rather badly broken.
>Asking for *C.*, for example, will return the same thing as *.*,
>regardless of whether the names in the directory contain `C'. Or at
>least it did for me. But for what you are doing, it should work to
>just give *.*.
MS-DOS (and its predecessor CP/M) treat wildcard characters differently
than UNIX. This has bitten many a programmer learning one after the
other. MS-DOS and CP/M filenames have a first name and a last name.
The first name can be up to eight characters. The last name can be
up to three characters long. The dot is always present whether you
like it or not. i.e. writing to file "abcd" will be the same as file
"abcd." . An asterisk will match any character (including void chars)
from its position in a name until the end of that name. The first name
is treated separately from the last name in this matter.
Here's the code a friend gave me to do wildcard searches on a PC.
I've never used it, so don't ask me anything about it. Instead ask
Steve Crawford {ihnp4|osu-cis}!n8emr!oink!snc about it.
File readme.jim: ***********************************************************
Hey,
find_first and find_next are in file find3.asm
dofind.c is a little test program I wrote to see that it does
indeed work.
Note in the beginning of find3.asm the db string called "fcb".
This is where the search pattern is defined; the ????????ASM matching
all files of type .ASM. You must change this to be whatever you want.
There's probably a better way to do search patterns (like passing a search
string to the find_ routines), but this is exactly what I needed for my
purposes. If either find_first or find_next don't find anything, they
return a 0.
The find_ routines were written for assembly under Microsoft Macro
Assembler V4.0 (or something like that). The C program is for msc.
Enjoy, and remember me in your will. Thanks for your help!!!
c'bag
File dofind.c: *************************************************************
#include <stdio.h>
#include <string.h>
char *fnames[20];
main()
{
int i;
char *ff,*sf; /* storage for file names */
char *malloc(),*find_first(), *find_next();
sf=malloc(13);
ff=find_first();
strcpy(sf,ff);
fnames[0]=sf;
for(i=1; (ff=find_next()); i++) {
sf=malloc(13); /* get pointer to string */
strcpy(sf,ff); /* copy file name */
fnames[i]=sf; /* store pointer */
}
for(i=0; (fnames[i]); i++) {
printf("file %d = %s\n", i, fnames[i]);
}
}
File find3.asm: **************************************************************
;
; find3.asm - find a file in the current directory
; 1/29/88 snc
;
; This is the third attempt. This routine is callable from C, fills
; an external array with the found names, and returns a pointer to the
; last array element filled.
;
DGROUP GROUP _DATA
ASSUME DS:DGROUP
_DATA SEGMENT WORD PUBLIC 'DATA'
sf db "NOT FOUND ON INT 11.$"
no db "FILE DOES NOT EXIST.$"
fcb db 0,"????????ASM"
db 25 dup(?)
buffer db 128 dup(?)
fbuf db 12 dup(?) ;file name buffer
_DATA ENDS
P_ENTER MACRO
PUSH BP
MOV BP,SP
push si
push di
PUSH ES
push ds
mov ax,DGROUP
mov ds,ax
ENDM
P_EXIT MACRO
pop ds
POP ES
pop di
pop si
mov sp,bp
POP BP
ENDM
_TEXT SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:_TEXT
PUBLIC _find_first, _find_next
_find_first PROC NEAR
P_ENTER
lea dx,buffer ;create a DTA
mov ah,1ah ;set DTA function
int 21h
lea dx,fcb ;do the search
mov ah,11h
int 21h
cmp al,0ffh ;find it?
jz short not_found ;exit if not
call output ;else, fix up file name
lea ax,fbuf
jmp short done
not_found:
xor ax,ax ;if no match, return 0
done:
P_EXIT
ret
_find_first ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_find_next PROC NEAR
P_ENTER
lea dx,fcb
mov ah,12h ;get next file
int 21h
cmp al,0ffh ;no more files?
jz short no_more ;exit routine if so
call output
lea ax,fbuf
jmp short go_back
no_more:
xor ax,ax ;if no files, return 0
go_back:
P_EXIT
ret
_find_next ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
output PROC NEAR
mov si,1
lea bx,buffer
lea di,fbuf
outchar:
mov dl,[bx][si]
cmp dl,20h ;blank space?
jz short skip ;skip it if so
mov [di],dl ;store character
inc di
skip:
inc si
cmp si,9 ;9 is 8 characters later from starting si
jz short period
jmp short outchar
period:
mov dl,2eh ;a period
mov [di],dl ;store character
inc di
outext:
mov dl,[bx][si]
mov [di],dl ;store character
inc di
inc si
cmp si,12
jnz short outext
mov [di],byte ptr 00 ;null terminate string
ret
output ENDP
_TEXT ENDS
END
End of files ****************************************************************
Remember to thank/flame Steve Crawford for the code.
--
Jim Prior {ihnp4|osu-cis}!n8emr!oink!jep jep at oink.UUCP
Pointers are my friend.
More information about the Comp.sys.att
mailing list