[ Next ] [ Previous ] | Chapter 4 - part II | [ Contents ] [ Chapter 3: Multitasking ] [ Chapter 4-III ] [ Chapter 5: Interprocess Communication ]

### 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.

pszFileName | Input address of a string containing file name
ppFileHandle | Output address of a returned file handle
pActionTaken | 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.

ulFileAttribute | Double word containing the files attributes
ulOpenFlag | Double word containing the desired open conditions
ulOpenMode | 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 | ?

[ Next ] [ Previous ] | Chapter 4 - part II | [ Contents ] [ Chapter 3: Multitasking ] [ Chapter 4-III ] [ Chapter 5: Interprocess Communication ]