OPEN_DIR
Syntax |
OPEN_DIR #channel, device_directory or OPEN_DIR #channel, [device_]directory(Toolkit II only) |
Location |
Toolkit II, THOR XVI |
This command is a specialised version of OPEN which is aimed at allowing you to read directories of any given drive device. The directory of a drive contains a copy of every file header which has ever been created on that medium.
When a file is deleted, its entry is blanked out (with zeros) in the directory, thus enabling recovery programs to actually still read the file (provided that nothing else has been written to the sectors where it was stored). It can therefore be very useful to access these directories, for example to provide the user with a selection of files to choose from.
It is however important to differentiate between directories and the output from the DIR command!
On Level-2 and Level-3 device drivers, it is quite easy to access a directory as the directory is stored in a file. For example, on a floppy disk, try:
COPY flp1_ TO scr
this will show the directory file.
Sub-directories are similar in that after the command:
MAKE_DIR flp1_Quill_
the file flp1_Quill will be created which contains a copy of all of the file headers for the files within that sub-directory.
Standard device drivers on the other hand are another kettle of fish, in that they allow you to create a file without any name. For example:
SAVE mdv1_
If you then:
COPY mdv1_ TO scr
you will see that this is exactly the same as if you had used:
SAVE mdv1_boot
(apart from the name of the file).
Such files are not revealed by DIR and can be used as a form of copy-protection by some programs. Because of this, you might suffer from a ‘Not Found’ (-7) error if you tried to:
COPY flp1_ TO scr
from a disk with a Level-1 device driver. A disk created on a level-1 driver does not look different to a level-2 driver.
If a file with a zero length name was created under a level-1 driver, then this file will only be accessible under the same driver level. To use the command OPEN_DIR, you will need to supply the intended channel number which must be an integer in the range 0…32767. As with OPEN this must be kept as low as possible. After this, comes the name of the directory to be opened. This should generally be simply the name of the device to be accessed, such as:
OPEN_DIR #ch,mdv1_
OPEN_DIR works correctly with standard device drivers even if there is a file on the drive without a name, eg. mdv1_.
If you have Level-2 device drivers, sub-directories may be accessed by providing the name of the drive plus the name of the sub-directory, for example:
OPEN_DIR #3,flp1_Quill
If Toolkit II is present, the default data device is supported (see DATAD$), although a directory will still need to be provided, therefore to simply access the default data directory, you will need to use:
OPEN_DIR #ch,''
Having opened the directory, you can then examine the file header for each file which has been stored on that drive by fetching blocks of 64 bytes from the channel at a time and examining each block per file.
Example
A short program which will provide a more detailed directory listing of any device:
100 WINDOW 448,200,32,16:PAPER 0:MODE 4:CLS
110 INK 7
120 INPUT 'Read directory of which device? - ';dev$
130 CLS:PRINT 'Directory of ';dev$
140 PRINT 'Filename';TO 40;'File length';TO 54;'Update date'
150 head_start=0
160 INK 4
170 OPEN_DIR #3,dev$:no_files=FLEN(#3)/64
180 FOR listing=1 TO no_files
190 BGET #3\head_start+0,flen1,flen2,flen3,flen4,faccess,ftype
200 flength=flen4+flen3*2^8+flen2*2^16+flen1*2^24-64
210 IF flength>0
220 GET #3\head_start+14, File$
230 BGET #3\head_start+52,fdate1,fdate2,fdate3,fdate4
240 fdate=fdate4+fdate3*2^8+fdate2*2^16+fdate1*2^24
245 IF LEN(File$)=0:File$='<Un-named>'
250 IF ftype<255
260 PRINT File$;TO 40;flength;TO 54;DATE$(fdate)
270 ELSE
280 PRINT File$&'->'
290 END IF
300 END IF
310 head_start=head_start+64
320 END FOR listing
330 CLOSE #3
340 INK 7:PRINT 'End of Listing'
NOTE 1
The OPEN_DIR command will close a channel which is already open with the same channel number prior to opening the new channel - do not try to OPEN_DIR #0 unless you have read the notes to OPEN!
NOTE 2
On QL ROMs (pre MG) there is a maximum of 32767 OPENs (in total) in a session.
NOTE 3
If you specify a device which is not actually used for the storage of files (for example:
OPEN_DIR#3,scr
OPEN_DIR#3,pipe_1000
then this command has exactly the same effect as the OPEN command.
NOTE 4
If the specified directory actually points to a non-directory file (or the file does not even exist), then OPEN_DIR will actually open the directory in which that file is located, for example, if the directory flp1_TK_ contained the file flp1_TK_FN_cde:
OPEN_DIR#3,flp1_TK_FN_cde
OPEN_DIR#3,flp1_TK_FN
OPEN_DIR#3,flp1_TK
would all have exactly the same effect.
NOTE 5
Because of the way in which Level-2 and Level-3 device drivers work, provided that you only use the name of an actual directory (or sub-directory) as the parameter, you could actually use OPEN or OPEN_IN instead of OPEN_DIR, but this has its limits, in that it would be useless with standard device drivers and creates havoc if the name of a non-directory file is supplied.
NOTE 6
Except under SMS, if a channel has been opened with OPEN_DIR to a main directory, no other channel can access that directory at the same time. Several channels can however be open to the same sub-directory (a bug perhaps) or to a sub-directory further down the tree, which for example allows:
100 OPEN_DIR #3,flp1_
110 OPEN_DIR #4,flp1_TK
120 OPEN_DIR #5,flp1_TK
but not:
100 OPEN_DIR #3,flp1_TK
110 OPEN_DIR #4,flp1_
This also has the result that whilst a channel which has been opened with OPEN_DIR is open to a main directory, commands such as DIR, WDIR, WDEL etc. will report ‘in use’ as they cannot access the directory themselves. The result of this (combined with the operation of the OPEN_DIR command) makes it actually possible to have two channels open to the main directory, by ensuring that the filename passed to the OPEN_DIR commands does not exist on the drive, for example:
OPEN_DIR #3,flp1_test
OPEN_DIR #4,flp1_test
will leave both channels #3 and #4 open to the main directory (flp1_).
Under SMS you can have several channels open to the same directory thereby avoiding these problems.
CROSS-REFERENCE
Please see OPEN. Commands such as FLEN, FGETH$ and HEADR allow you to examine parts of each files header - see FGETH$ for details of the file header. FOP_DIR is an error trapped version of OPEN_DIR. The Minerva variant of OPEN, OPEN_IN and OPEN_NEW can all be made to work in a similar way to OPEN_DIR.