File I/O and Extended Attributes - part II
More on DosOpen
Before we continue with the EA example, it might be beneficial to cover
the DosOpen API in greater detail.
APIRET DosOpen(
PSZ
pszFileName, /* Address of the ASCIIZ path name of the file or device to
be opened. */
PHFILE pHf,
/* Address of the handle for the file. */
PULONG pulAction,
/* Address of the variable that receives the value that specifies the action
taken by the DosOpen function. */
ULONG
cbFile, /* New logical size of the file (end
of data, EOD), in bytes. */
ULONG
ulAttribute, /* File attribute information. */
ULONG
fsOpenFlags, /* The action to be taken depending on whether the file exists
or does not exist.*/
ULONG
fsOpenMode, /* The mode of the open function. Possible values are
shown in the following list: */
PEAOP2 peaop2);
/* Extended attributes. */
The first three arguments are clearly identified.
|
Input address of a string containing file name
|
|
Output address of a returned file handle
|
|
Output address of a specified action variable
|
The action variable on output will have the following useful values:
Table 4.3 Values of the Action Variable
#define |
Value |
Meaning |
FILE_EXISTED |
1
|
File existed prior to call |
FILE_CREATED |
2
|
File was created as the result of the call |
FILE_TRUNCATED |
3
|
Existing file was changed by the call |
The next three input arguments can create the most confusion.
|
Double word containing the files attributes
|
|
Double word containing the desired open conditions
|
|
Double word containing the mode/sharing conditions
|
They create confusion because the same DosOpen call
can be used to open files, disk volumes, pipes, and other devices. For
example, if a user wanted to open a named pipe, some of the sharing flags
and the ulFileSize value are ignored by the operating system because the
pipes buffer sizes are specified by the DosCreareNPipe
API. Also, the ulFileSize may not make sense if the user is opening a disk
volume for direct access. Sometimes device drivers allow DosOpen calls
with a device name specified in place of the pszFileName. It is still a
null-terminated string, but in the case of a device driver the string contains
the device name, such as "DEVICE$". Specifying ulFileSize or other ulFileAttribute
flags makes no sense, and thus some of the input parameters are ignored.
All three input flag parameters are bit-encoded, meaning each bit that
is set represents a new or unique flag condition. Most of the bits can
be set in combination. All of the flags are 32 bits wide, but not all of
the 32 bits are used at this time. Some are reserved for future use and
must be set to zero. For example, the ulFileAttribute bit values are shown
in Figure 4.1.
Figure 4.1 File attribute bit flags.
0 |
FILE_READONLY |
1 |
FILE_HIDDEN |
2 |
FILE_SYSTEM |
3 |
RESERVED, must be set to ZERO |
4 |
FILE_DIRECTORY |
5
|
FILE_ARCHIVED |
|
6-15 |
RESERVED, must be set to ZERO |
16-31 |
RESERVED, must be set to ZERO |
|
Table 4.4 describes the file attribute bit flags.
Table 4.4 File Attribute Bit Flag Descriptions
Value |
Description |
FILE_READONLY |
File can be read but not written to |
FILE_NORMAL |
File can be read and written to |
FILE_HIDDEN |
File is a hidden file |
FILE_SYSTEM |
File is a system file |
FILE_DIRECTORY |
File is a subdirectory |
FILE_ARCHIVED |
File has archive bit set |
To allow the file read-only access and to declare the file to be of
system type, the following combination is used.
ulFileAttribute = FILE_READONLY | FILE_SYSTEM;
The ulOpenFlag describes the actions that the DosOpen
will perform based on the bit encoding specified by the programmer. These
actions deal with conditions of file existence, replacement, and creation.
A user may want to allow the DosOpen API to fail, if
the file already exists. If so, specify:
ulOpenFlag = OPEN_ACTION_FAIL_IF_EXISTS;
If the user wants the DosOpen call to open the
file if it exists, and fail if it does not exist, the following should
be specified:
ulOpenFlag = OPEN_ACTION_FAIL_IF_NEW
|
OPEN_ACTION_OPEN_IF_EXISTS;
Figure 4.2 depicts additional file open action flags.
Figure 4.2 File Open action flags.
0 |
OPEN_ACTION_FAIL_IF_EXISTS |
0000 |
OPEN_ACTION_OPEN_IF_EXISTS |
0001 |
OPEN_ACTION_REPLACE_IF_EXISTS |
0010 |
|
1 |
2 |
3 |
4 |
OPEN_ACTION_FAIL_IF_NEW |
0000 |
OPEN_ACTION_CREATE_IF_NEW |
0001 |
|
5 |
6 |
7 |
|
8-15 |
RESERVED, must be set to ZERO |
16-31 |
RESERVED, must be set to ZERO |
|
Table 4.5 describes the file open action flags that are available.
Table 4.5 File Open Action Flags
Value |
Description |
OPEN_ACTION_FAIL_IF_EXISTS |
DosOpen will fail if the file already exists; file is created |
OPEN_ACTION_OPEN_IF_EXISTS |
File is opened if it already exists |
OPEN_ACTION_REPLACE_IF_EXISTS |
File is replaced if it already exists |
OPEN_ACTION_FAIL_IF_NEW |
DosOpen will fail if file does not exist; file is opened if it does
exist |
OPEN_ACTION_CREATE_IF_NEW |
File is created if it does not exist |
The ulOpenMode describes the mode that the open call will set for the
file object. This flag will tell the system how to behave when other users
request access to the file that is currently in use by someone else. It
is here that the system write-through buffering is specified and the error
reporting is decided. For example, the user may want to allow the system
to use its cache to transfer the data between the application and the file
object, but the actual write must complete prior to the return of the call.
Also, the user may want to have all of the errors reported directly to
his or her application and not through the system critical-error handle..
On top of that, a programmer may want to open this file in read-only mode
and not allow anyone else write access to the file while in use. Wow! Well,
for a combination of conditions like that, use the following flags:
ulOpenFlag = OPEN_FLAGS_WRITE_THROUGH
| OPEN_FLAGS_FAIL_ON_ERROR
| OPEN_SHARE_DENY_WRITE
| OPEN_ACCESS_READONLY ;
Thus, a. number of conditions can be specified, and file management becomes
a tedious and time-consuming task for the programmer and the operating
system. Figure 4.3 depicts the available open mode flag.
Figure 4.3 Open mode flags.
0 |
OPEN_ACCESS_READONLY |
000 |
OPEN_ACCESS_WRITEONLY |
001 |
OPEN_ACCESS_READWRITE |
010 |
|
1 |
2 |
3 |
RESERVED, must be set to ZERO |
4 |
OPEN_SHARE_DENYREADWRITE |
001 |
OPEN_SHARE_DENYWRITE |
010 |
OPEN_SHARE_DENYREAD |
011 |
OPEN_SHARE_DENYNONE |
100 |
|
5 |
6 |
7 |
OPEN_FLAGS_NOINHERIT |
8 |
OPEN_FLAGS_NO_LOCALITY |
000 |
OPEN_FLAGS_SEQUENTIAL |
001 |
OPEN_FLAGS_RANDOM |
010 |
OPEN_FLAGS_RANDOMSEQUENTIAL |
011 |
|
9 |
10 |
|
11
|
RESERVED, must be set to ZERO |
12
|
OPEN_FLAGS_NO_CACHE |
13
|
OPEN_FLAGS_FAIL_ON_ERROR |
14
|
OPEN_FLAGS_WRITE_THROUGH |
15
|
OPEN_FLAGS_DASD |
16-17 |
RESERVED, must be set to ZERO |
18 |
OPEN_FLAGS_NONSPOOLED |
19-27 |
RESERVED, must be set to ZERO |
28 |
OPEN_SHARE_DENYLEGACY |
29 |
RESERVED, must be set to ZERO |
30 |
OPEN_FLAGS_PROTECTED_HANDLE |
31 |
RESERVED, must be set to ZERO |
|
Table 4.6 Open Mode Flag Descriptions
Value |
Description |
OPEN_ACCESS_READONLY |
File is given only read access |
OPEN_ACCESS_WRITEONLY |
File is given only write access |
OPEN_ACCESS_READWRITE |
File Is given read/write access |
OPEN_SHARE_DENYREADWRITE |
Other processes cannot be given read or write access |
OPEN_SHARE_DENYWRITE |
Other processes cannot be given write access |
OPEN_SHARE_DENYREAD |
Other processes cannot be given read access |
OPEN_SHARE_DENYNONE |
Other processes can have read and write access to file |
OPEN_FLAGS_NOINHERIT |
File handle is not inherited to spawned processes |
OPEN_FLAGS_SEQUENTIAL |
File is opened for mainly sequential access |
OPEN_FLAGS_RANDOM |
File is opened for mainly random access |
OPEN_FLAGS_RANDOMSEQUENTIAL |
File is opened for both random and sequential access |
OPEN_FLAGS_NO_LOCALITY |
File locality is not known |
OPEN_FLAGS_NO_CACHE |
No file data is placed in cache |
OPEN_FLAGS_FAIL_ON_ERROR |
Media I/O errors are reported by return code rather than through
the system error handler |
OPEN_FLAGS_WRITE_THROUGH |
File writes may go through cache but will be completed before the write
call returns |
OPEN_FLAGS_DASD |
File is a drive to be opened for direct access |
OPEN_FLAGS_NONSPOOLED |
? |
OPEN_SHARE_DENYLEGACY |
? |
OPEN_FLAGS_PROTECTED_HANDLE |
? |