Xref: utzoo comp.sys.att:2880 comp.sys.misc:1310 Path: utzoo!utgpu!water!watmath!clyde!att-cb!gwspc!n8emr!oink!jep From: jep@oink.UUCP (James E. Prior) Newsgroups: comp.sys.att,comp.sys.misc Subject: Re: Seeking a method to "read" a DOS directory Message-ID: <253@oink.UUCP> Date: 26 Mar 88 00:42:28 GMT References: <902@cblpe.ATT.COM> <1001@mcgill-vision.UUCP> Reply-To: jep@oink.UUCP (James E. Prior) Organization: Random Prime Research Institute Columbus, Ohio Lines: 220 In article <1001@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: >In article <902@cblpe.ATT.COM>, jrm@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 #include 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@oink.UUCP Pointers are my friend.