Understanding the structure of the file control block is the key to success with the FCB family of file and record functions. An FCB is a 37-byte data structure allocated within the application program's memory space; it is divided into many fields (Figure 8-1). Typically, the program initializes an FCB with a drive code, a filename, and an extension (conveniently accomplished with the parse-filename service, Int 21H Function 29H) and then passes the address of the FCB to MS-DOS to open or create the file. If the file is successfully opened or created, MS-DOS fills in certain fields of the FCB with information from the file's entry in the disk directory. This information includes the file's exact size in bytes and the date and time the file was created or last updated. MS-DOS also places certain other information within a reserved area of the FCB; however, this area is used by the operating system for its own purposes and varies among different versions of MS-DOS. Application programs should never modify the reserved area.
For compatibility with CP/M, MS-DOS automatically sets the record-size field of the FCB to 128 bytes. If the program does not want to use this default record size, it must place the desired size (in bytes) into the record-size field after the open or create operation. Subsequently, when the program needs to read or write records from the file, it must pass the address of the FCB to MS-DOS; MS-DOS, in turn, keeps the FCB updated with information about the current position of the file pointer and the size of the file. Data is always read to or written from the current disk transfer area (DTA), whose address is set with Int 21H Function 1AH. If the application program wants to perform random record access, it must set the record number into the FCB before issuing each function call; when sequential record access is being used, MS-DOS maintains the FCB and no special intervention is needed from the application.
Figure 8-1. Normal file control block. Total length is 37 bytes (25H bytes). See notes on pages 133—34.
Please refer to the printed book for this figure.
In general, MS-DOS functions that use FCBs accept the full address of the FCB in the DS:DX register and pass back a return code in the AL register (Figure 8-2). For file-management calls (open, close, create, and delete), this return code is zero if the function was successful and 0FFH (255) if the function failed. For the FCB-type record read and write functions, the success code returned in the AL register is again zero, but there are several failure codes. Under MS-DOS version 3.0 or later, more detailed error reporting can be obtained by calling Int 21H Function 59H (Get Extended Error Information) after a failed FCB function call.
When a program is loaded under MS-DOS, the operating system sets up two FCBs in the program segment prefix, at offsets 005CH and 006CH. These are often referred to as the default FCBs, and they are included to provide upward compatibility from CP/M. MS-DOS parses the first two parameters in the command line that invokes the program (excluding any redirection directives) into the default FCBs, under the assumption that they may be file specifications. The application must determine whether they really are filenames or not. In addition, because the default FCBs overlap and are not in a particularly convenient location (especially for .EXE programs), they usually must be copied elsewhere in order to be used safely. (See Chapter 3.)
; filename was previously
; parsed into "my_fcb"
mov dx,seg my_fcb ; DS:DX = address of
mov ds,dx ; file control block
mov dx,offset my_fcb
mov ah,0fh ; function 0fh = open
int 21h
or al,al ; was open successful?
jnz error ; no, jump to error routine
.
.
.
my_fcb db 37 dup (0) ; file control block
Figure 8-2. A typical FCB file operation. This sequence of code attempts to open the file whose name was previously parsed into the FCB named my_fcb.
Note that the structures of FCBs under CP/M and MS-DOS are not identical. However, the differences lie chiefly in the reserved areas of the FCBs (which should not be manipulated by application programs in any case), so well-behaved CP/M applications should be relatively easy to port into MS-DOS. It seems, however, that few such applications exist. Many of the tricks that were played by clever CP/M programmers to increase performance or circumvent the limitations of that operating system can cause severe problems under MS-DOS, particularly in networking environments. At any rate, much better performance can be achieved by thoroughly rewriting the CP/M applications to take advantage of the superior capabilities of MS-DOS.
You can use a special FCB variant called an extended file control block to create or access files with special attributes (such as hidden or read-only files), volume labels, and subdirectories. An extended FCB has a 7-byte header followed by the 37-byte structure of a normal FCB (Figure 8-3). The first byte contains 0FFH, which could never be a legal drive code and thus indicates to MS-DOS that an extended FCB is being used. The next 5 bytes are reserved and are unused in current versions of MS-DOS. The seventh byte contains the attribute of the special file type that is being accessed. (Attribute bytes are discussed in more detail in Chapter 9.) Any MS-DOS function that uses a normal FCB can also use an extended FCB.
The FCB file- and record-management functions may be gathered into the following broad classifications:
Figure 8-3. Extended file control block. Total length is 44 bytes (2CH bytes). See notes on pages 133—34.
Please refer to the printed book for this figure.
Function Action
Common FCB file operations
0FH Open file.
10H Close file.
16H Create file.
Common FCB record operations
14H Perform sequential read.
15H Perform sequential write.
21H Perform random read.
22H Perform random write.
27H Perform random block read.
28H Perform random block write.
Other vital FCB operations
1AH Set disk transfer address.
29H Parse filename.
Less commonly used FCB file operations
13H Delete file.
17H Rename file.
Less commonly used FCB record operations
23H Obtain file size.
24H Set relative-record number.
Several of these functions have special properties. For example, Int 21H Functions 27H (Random Block Read) and 28H (Random Block Write) allow reading and writing of multiple records of any size and also update the random-record field automatically (unlike Int 21H Functions 21H and 22H). Int 21H Function 28H can truncate a file to any desired size, and Int 21H Function 17H used with an extended FCB can alter a volume label or rename a subdirectory.
Section 2 of this book, "MS-DOS Functions Reference," gives detailed specifications for each of the FCB file and record functions, along with assembly-language examples. It is also instructive to compare the preceding groups with the corresponding groups of handle-type functions listed on pages 140—41.
Notes for Figures 8-1 and 8-3
1.The drive identification is a binary number: 00=default drive, 01=drive A:, 02=drive B:, and so on. If the application program supplies the drive code as zero (default drive), MS-DOS fills in the code for the actual current disk drive after a successful open or create call.
2.File and extension names must be left justified and padded with blanks.
3.The file size, date, time, and reserved fields should not be modified by applications.
4.All word fields are stored with the least significant byte at the lower address.
5.The relative-record field is treated as 4 bytes if the record size is less than 64 bytes; otherwise, only the first 3 bytes of this field are used.
6.The file-size field is in the same format as in the directory, with the less significant word at the lower address.
7.The date field is mapped as in the directory. Viewed as a 16-bit word (as it would appear in a register), the field is broken down as follows:
F E D C B A 9 8 7 6 5 4 3 2 1 0
Bits Contents 00H—04H Day (1—31) 05H—08H Month (1—12) 09H—0FH Year, relative to 1980
8.The time field is mapped as in the directory. Viewed as a 16-bit word (as it would appear in a register), the field is broken down as follows:
F E D C B A 9 8 7 6 5 4 3 2 1 0
Bits Contents 00H—04H 2-second increments (0—29) 05H—0AH Minutes (0—59) 0BH—0FH Hours (0—23)
9.The current-block and current-record numbers are used together on sequential reads and writes. This simulates the behavior of CP/M.
10.The Int 21H open (0FH) and create (16H) functions set the record-size field to 128 bytes, to provide compatibility with CP/M. If you use another record size, you must fill it in after the open or create operation.
11.An 0FFH (255) in the first byte of the structure signifies that it is an extended file control block. You can use extended FCBs with any of the functions that accept an ordinary FCB. (See also note 12.)
12.The attribute byte in an extended FCB allows access to files with the special characteristics hidden, system, or read-only. You can also use extended FCBs to read volume labels and the contents of special subdirectory files.