[comp.sys.ibm.pc] How do you read an MS-DOS directory?

psc@lzaz.ATT.COM (Paul S. R. Chisholm) (05/13/87)

< "I'm *not* expendable, I'm *not* stupid, and I'm *NOT* going!" >

Maybe I'm missing the point, but I can't see any way to read a
directory (or subdirectory) using the DOS functions.  The obvious thing
is to just open "FOO" (or "FOO."), but I got an "Access denied" error
code.  I supposed I could use the BIOS diskette services to find the
FAT, and chain my way through the root directory and any necessary
subdirectories till I find my subdirectory, calculating the sectors by
hand.  No, I'm not getting burned by the "c:\newline\backsp" bug (where
C programmers use backslash for DOS pathnames, and forget C also used
backslashes for magic characters).  I don't want to write to the
directory, only see what files are in it and how long they are (without
reading all of all the files), perhaps recursively.

There are forty-two thousand versions of the UNIX(R) ls command for
DOS, so it can't be *that* hard . . . unless there's a DOS stat()
function in the C library you're using.  There will be in the next
version of the one I'm using, I hope.  (Don't ask.)

Follow up if you must, reply by mail if you can; I'll summarize.

-Paul S. R. Chisholm, UUCP {ihnp4,cbosgd,allegra,vax135,mtune}!lznv!psc
AT&T Mail !psrchisholm, Internet psc@lznv.att.com
I'm not speaking for my employer, I'm just speaking my mind.
I'm not speaking for the company, I'm just speaking my mind.

psc@lzaz.ATT.COM (Paul S. R. Chisholm) (05/13/87)

Maybe I'm missing the point, but I can't see any way to read a
directory (or subdirectory) using the DOS functions.  The obvious thing
is to just open "FOO" (or "FOO."), but I got an "Access denied" error
code.  I supposed I could use the BIOS diskette services to find the
FAT, and chain my way through the root directory and any necessary
subdirectories till I find my subdirectory, calculating the sectors by
hand.  No, I'm not getting burned by the "c:\newline\backsp" bug (where
C programmers use backslash for DOS pathnames, and forget C also used
backslashes for magic characters).  I don't want to write to the
directory, only see what files are in it and how long they are (without
reading all of all the files), perhaps recursively.

There are forty-two thousand versions of the UNIX(R) ls command for
DOS, so it can't be *that* hard . . . unless there's a DOS stat()
function in the C library you're using.  There will be in the next
version of the one I'm using, I hope.  (Don't ask.)

Follow up if you must, reply by mail if you can; I'll summarize.

-Paul S. R. Chisholm, UUCP {ihnp4,cbosgd,allegra,vax135,mtune}!lznv!psc
AT&T Mail !psrchisholm, Internet psc@lznv.att.com
I'm not speaking for my employer, I'm just speaking my mind.

dhesi@bsu-cs.UUCP (05/16/87)

In article <63@lzaz.ATT.COM> psc@lzaz.ATT.COM (Paul S. R. Chisholm) writes:
>Maybe I'm missing the point, but I can't see any way to read a
>directory (or subdirectory) using the DOS functions. 

The MS-DOS calls FindFirst and FindNext accept an attribute byte and
a filename pattern and return the names of all matching files.  If
the attribute byte is correctly supplied the names will include
directories too.

One you have the name of a directory, you can then append "*.*" to
its name and use FindFirst and FindNext again recursively.

These calls will also return some additional information such as
file size and date.
-- 
Rahul Dhesi         UUCP:  {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi

madd@bucsb.bu.edu.UUCP (Jim "Jack" Frost) (05/17/87)

In article <63@lzaz.ATT.COM> psc@lzaz.ATT.COM (Paul S. R. Chisholm) writes:
>Maybe I'm missing the point, but I can't see any way to read a
>directory (or subdirectory) using the DOS functions.  The obvious thing
>is to just open "FOO" (or "FOO."), but I got an "Access denied" error
>code.  I supposed I could use the BIOS diskette services to find the
>FAT, and chain my way through the root directory and any necessary
>subdirectories till I find my subdirectory, calculating the sectors by
>hand.  No, I'm not getting burned by the "c:\newline\backsp" bug (where
>C programmers use backslash for DOS pathnames, and forget C also used
>backslashes for magic characters).  I don't want to write to the
>directory, only see what files are in it and how long they are (without
>reading all of all the files), perhaps recursively.

I'm not going to give you straight code for it, but here's an outlie
of how to do it.  Most of the information here came from the MSDOS
Tech Ref manual, so you can always just go look it up.

1)  You need to tell msdos where the DTA address is, because this is
where the info is going to be stored.  This is function 1AH.  Set
AH=1AH, DS and DX to the address of the DTA (DS:DX), and do an INT
21H.  I don't remember how big the DTA area is supposed to be, so
you'll have to look it up or experiment.

2) Call "FIND FIRST", which is function 4EH.  To call this, set
AH=4EH, DS:DX should point to an ASCIIZ pathname with matching
characters (like "????????.???" to find any file).  CX should contain
the file attribute.  File attributes are:

  01H Read only file
  02H Hidden file
  04H System file
  10H Subdirectory
  20H Archived file

3) The returned data will be in the DTA area, and will be formatted as
follows:

  21 bytes of stuff ("Reserved for DOS use on subsequent "FIND NEXT"
     calls)
  1 byte (file attribute)
  2 bytes (file time)
  2 bytes (file date)
  2 bytes (low byte of file size)
  2 bytes (high byte of file size)
  13 bytes (name and extension of file found, followed by a zero byte)

I won't get into decoding date and time right now, but you can always
look it up.


4) To find subsequent matches, use the "FIND NEXT" command, which is
function 4FH.  It assumes that "FIND FIRST" has already been found and
uses the DTA information to find the next entry.

5) As soon as no more entries are to be found, AX will be set to 18
(decimal, 12H) indicating "no more files."  Note that SOMETIMES a null
file name will be returned in the call before you receive the 12H
return code.  This is from personal experience.

The Turbo Pascal Tutorial gives a good description (and a nice
routine) of how to get a directory.  I hacked it into a general
purpose routine to return a linked list of entries.  There are
probably some books out there that describe how to do this as well....

Hope this is helpful.  Happy hacking!

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
          Jim Frost * The Madd Hacker | UUCP: ..!harvard!bu-cs!bucsb!madd
  H H                                 | ARPA:           madd@bucsb.bu.edu
H-C-C-OH <- heehee          +---------+----------------------------------
  H H                       | "We are strangers in a world we never made"

tim@j.cc.purdue.edu (Timothy Lange) (05/17/87)

Using an extended FCB with the proper file name (or wild cards), and the
attribute for 'directory' will allow you to find and open directory
files.  The thing I ran into was the size of the directory file is
always returned as zero!  No big deal though, you know you have at least
one cluster to work with and when you find a directory entry that is all
zeroes that is the end of the file.  So I just reset the size to
something large and write my code to detect end of file by looking at
the values in each directory entry.  I wrote my own directory
alphabetizer once, so it can be done fairly easiely.
-- 
Timothy Lange / PC Learning Resource Center / Mathmatical Sciences Bldg.
Purdue University Computing Center / West Lafayette, IN  47907
317-494-1787 / tim@j.cc.purdue.edu

psfales@ihlpe.ATT.COM (Peter Fales) (05/19/87)

In article <62@lzaz.ATT.COM>, psc@lzaz.ATT.COM (Paul S. R. Chisholm) writes:
> 
> Maybe I'm missing the point, but I can't see any way to read a
> directory (or subdirectory) using the DOS functions.  The obvious thing
> is to just open "FOO" (or "FOO."), but I got an "Access denied" error
> code.

The standard trick is use the DOS functions "find first" and "find next"
to find all files which match "dir/subdir1/subdir2/*.*" or whatever.

It is likely that your compiler library has functions to simplify this
procedure.  In my compiler they are called opendir() and readdir(), I
believe the names are stolen from similar functions under BSD UNIX.

-- 
Peter Fales		UUCP:	...ihnp4!ihlpe!psfales
			work:	(312) 979-7784
				AT&T Information Systems, IW 1Z-243
				1100 E. Warrenville Rd., IL 60566