Documentation updates

This commit is contained in:
Jeff Parsons 2016-02-19 12:23:12 -08:00
commit 6b5e9ef1d4
17 changed files with 626 additions and 73 deletions

View file

@ -6,6 +6,9 @@ redirect_from:
- /pubs/pc/programming/os2/microsoft/ptk/1.0/
---
[Microsoft OS/2 Programmer's Toolkit](../../)
---
Welcome
---

View file

@ -6,10 +6,7 @@ redirect_from:
- /pubs/pc/programming/os2/microsoft/ptk/1.0/plguide/
---
Programmer's Toolkit
---
Programmer's Learning Guide
[Microsoft OS/2 Programmer's Learning Guide](../)
---
Version 1.0
@ -17,27 +14,27 @@ Version 1.0
### Contents
* 1.0 [Introduction](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/)
* 1.1 [Overview](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/#overview)
* 1.2 [What You Need to Start](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/#what-you-need-to-start)
* 1.3 [What This Guide Covers](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/#what-this-guide-covers)
* 1.4 [The Lqh Sample Program](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/#the-lqh-sample-program)
* 1.5 [MS OS/2 Sample Programs](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/#ms-os2-sample-programs)
* 1.6 [MS OS/2 and the C Run-time Library](/pubs/pc/software/os2/microsoft/ptk10/plguide/chapter1/#ms-os2-and-the-c-run-time-library)
* 2.0 Overview
* 2.1 Introduction
* 2.2 Creating an MS OS/2 Program
* 2.3 C-Language Header Files
* 2.4 A Simple Program: Echoing the Command Line
* 2.5 Using the MS OS/2 Naming Conventions
* 2.6 Using Structures: Getting the Time of Day
* 2.7 Using Bit Masks
* 2.8 Sharing Resources: Playing a Tune
* 3.0 Input and Output
* 3.1 Introduction
* 3.2 Opening Files
* 3.3 Reading and Writing to Files
* 3.4 Creating a File
* 1.0 [Introduction](chapter1/)
* 1.1 [Overview](chapter1/#overview)
* 1.2 [What You Need to Start](chapter1/#what-you-need-to-start)
* 1.3 [What This Guide Covers](chapter1/#what-this-guide-covers)
* 1.4 [The Lqh Sample Program](chapter1/#the-lqh-sample-program)
* 1.5 [MS OS/2 Sample Programs](chapter1/#ms-os2-sample-programs)
* 1.6 [MS OS/2 and the C Run-time Library](chapter1/#ms-os2-and-the-c-run-time-library)
* 2.0 [Overview](chapter2/)
* 2.1 [Introduction](chapter2/#introduction)
* 2.2 [Creating an MS OS/2 Program](chapter2/#creating-an-ms-os2-program)
* 2.3 [C-Language Header Files](chapter2/#c-language-header-files)
* 2.4 [A Simple Program: Echoing the Command Line](chapter2/#a-simple-program-echoing-the-command-line)
* 2.5 [Using the MS OS/2 Naming Conventions](chapter2/#using-the-ms-os2-naming-conventions)
* 2.6 [Using Structures: Getting the Time of Day](chapter2/#using-structures-getting-the-time-of-day)
* 2.7 [Using Bit Masks](chapter2/#using-bit-masks)
* 2.8 [Sharing Resources: Playing a Tune](chapter2/#sharing-resources-playing-a-tune)
* 3.0 [Input and Output](chapter3/)
* 3.1 [Introduction](chapter3/#introduction)
* 3.2 [Opening Files](chapter3/#opening-files)
* 3.3 [Reading and Writing to Files](chapter3/#reading-and-writing-to-files)
* 3.4 [Creating a File](chapter3/#creating-a-file)
* 3.5 Closing a File
* 3.6 Standard Input and Output Files
* 3.7 Redirecting Standard Files

View file

@ -6,7 +6,7 @@ redirect_from:
- /pubs/pc/programming/os2/microsoft/ptk/1.0/plguide/chapter1/
---
Microsoft OS/2 Programmer's Learning Guide
[Microsoft OS/2 Programmer's Learning Guide](../)
---
Introduction
@ -111,6 +111,7 @@ threads | Creates and manages threads.
timer | Sleeps and then beeps three times.
version | Prints the DOS version (bound).
vioreg | Registers a Vio subsystem.
|
The following sample programs are extended examples that combine many of the features illustrated in the previous
samples:
@ -127,6 +128,7 @@ mandel | Displays the Mandelbrot set, using EGA high-resolution graphics.
bigben | Displays a digital clock, demonstrating the Vio functions (bound).
setega | Sets 25/43-line mode (bound).
chaser | Demonstrates the use of threads (requires a mouse).
|
### 1.6 MS OS/2 and the C Run-time Library

View file

@ -0,0 +1,385 @@
---
layout: page
title: "Microsoft OS/2 Programmer's Learning Guide: Overview"
permalink: /pubs/pc/software/os2/microsoft/ptk10/plguide/chapter2/
---
[Microsoft OS/2 Programmer's Learning Guide](../)
---
Overview
---
### 2.1 Introduction
This chapter explains the basic steps needed to create an MS OS/2
C-language program. In particular, it explains how to do the following:
+ Use the **main** function for your program starting point.
+ Use the *os2.h* header file for function declarations.
+ Use INCL_ constants to selectively enable function groups.
+ Use your program's command line.
+ Use MS OS/2 naming conventions in your program sources.
+ Use structures in MS OS/2 function calls.
+ Use the AND and OR operators to examine and modify bit masks.
+ Use care in programs that access shared resources.
### 2.2 Creating an MS OS/2 Program
Creating an MS OS/2 C-language program is no different than creating any other type of C-language program.
You use the **main** function as your program starting point and create and call as many other functions as
you need to complete the task. The following simple MS OS/2 program copies the line "Hello, world" to the screen:
#include <os2.h>
main( )
{
USHORT cbWritten;
DosWrite(1, "Hello, world\r\n", 14, &cbWritten);
}
The MS OS/2 system functions use many structures, data types, and constants that are not part of the standard
C language. For example, the data type **USHORT** is a special MS OS/2 data type that specifies an unsigned short
integer. To access these items, you need to include the MS OS/2 header file *os2.h* at the beginning of your program
source file.
The MS OS/2 system functions are not standard C functions. They use the Pascal calling convention. This means,
for example, that they expect parameters to be passed in right-to-left order instead of the standard left­to-right
order of C functions. Therefore, to use the MS OS/2 functions in a C-language program, you must make sure they are
declared with the **pascal** keyword, which directs the C compiler to generate proper instructions for the function
call. Fortunately, all MS OS/2 functions are declared within the *os2.h* file, so including the file saves you the
trouble of declaring each function individually.
The *os2.h* file also declares the parameter types for each function. This is convenient since many function
parameters would otherwise require type casting to avoid compiler errors. For example, the **DosWrite** function
shown in the previous example requires the second parameter to be a full 32-bit (far) address to the given string.
Since the *os2.h* file declares the second parameter as such, the cast is carried out for you by the compiler.
### 2.3 C-Language Header Files
The MS OS/2 C-language header file *os2.h* contains the definitions you need to use the functions, data types,
structures, and constants described in the *Microsoft Operating System/2 Programmer's Reference*.
When you include the *os2.h* file, the C preprocessor automatically defines many, but not all, of the most commonly
used MS OS/2 functions. The *os2.h* header file is the first file of a set of files that contains the MS OS/2 function
definitions. Each file contains definitions for the functions, data types, structures, and constants associated with
a specific group of MS OS/2 functions. To minimize the time required to process the many header files, each function
group is conditionally processed depending on whether a corresponding constant is defined within the program source file.
The following is a list of these constants with descriptions of the function groups they represent:
**Constant** | **Meaning**
:----------------- | :-------------
INCL_BASE | Includes all MS OS/2 1.0 system function definitions.
INCL_DOS | Includes all MS OS/2 1.0 kernel function definitions (Dos).
INCL_SUB | Includes all MS OS/2 1.0 video, keyboard, and mouse functions (Vio, Kbd, and Mou).
INCL_DOSDATETIME | Includes all date/time and timer functions.
INCL_DOSDEVICES | Includes the device and IOPL support functions.
INCL_DOSERRORS | Includes the MS OS/2 error constants.
INCL_DOSFILEMGR | Includes all file-management functions.
INCL_DOSINFOSEG | Includes all information-segment functions.
INCL_DOSMEMMGR | Includes all memory-management functions.
INCL_DOSMODULEMGR | Includes all module-manager functions.
INCL_DOSMONITORS | Includes all monitor functions.
INCL_DOSNLS | Includes national-language-support functions.
INCL_DOSPROCESS | Includes all process- and thread-support functions.
INCL_DOSQUEUES | Includes all queue and other miscellaneous functions.
INCL_DOSRESOURCES | Includes resource-support functions (not available in MS OS/2 1.0).
INCL_DOSSEMAPHORES | Includes all semaphore functions.
INCL_DOSSESMGR | Includes all session-manager functions.
INCL_DOSSIGNALS | Includes all signal functions.
INCL_NOCOMMON | Excludes any function group not explicitly defined.
|
To use a function within your program function, you simply define the corresponding constant by using the #define
directive before including the *os2.h* file. For example, the following program includes definitions for the
memory-manager and file-system functions:
#define INCL_DOSMEMMGR
#define INCL_DOSFILEMGR
#include <os2.h>
main( )
{
...
}
Once you have defined a constant, you may use any function, structure, or data type in that function group.
### 2.4 A Simple Program: Echoing the Command Line
In standard C-language programs, you can use the *argc* and *argv* parameters of the main function to retrieve
individual copies of the command­line arguments. You can use these parameters in MS OS/2 programs, but you can also
retrieve the entire command line, exactly as the user typed it, by using the **DosGetEnv** function.
When it starts a program, MS OS/2 prepares an environment segment for the program that contains definitions of all
environment variables, as well as of the command line. The **DosGetEnv** function retrieves the segment selector
for the program's environment segment and the address offset within that segment for the start of the command line.
You can echo the command line on the screen by using the **DosGetEnv** function to get the address of the command
line in the environment segment, as shown in the following sample program:
#define INCL_DOSQUEUES
#include <os2.h>
main( )
{
SEL selEnvironment;
USHORT offCommand;
PSZ pszCommandLine;
USHORT cbWritten;
USHORT i, cch;
DosGetEnv(&selEnvironment, &offCommand);
pszCommandLine = MAKEP(selEnvironment, offCommand);
for (i = 0; pszCommandLine[i]; i++);
for (i++, cch = 0; pszCommandLine[cch + i]; cch++);
DosWrite(1, &pszCommandLine[i] , cch, &cbWritten);
}
The command line is in two parts. The first part is the program name, terminated by a zero byte. The second part
is the rest of the command line, terminated by two zero bytes. This sample program echoes the command line by skipping
over the program name, then writing everything up to the next zero byte to the screen. The first **for** statement
skips over the command name; the second for statement computes the length of the string. The **MAKEP** macro creates
the far pointer that is needed to access the command line in the environment segment.
You can also examine your program's environment by using the selector retrieved by the **DosGetEnv** function.
The program's environment consists of the environment variables that have been declared and passed to the program.
Each program has a unique environment that is typically inherited from the program that started it; for example,
from the MS OS/2 command processor **cmd**.
You can use the **DosScanEnv** function to scan for a specific environment variable. This function takes the name
of the environment variable that you are interested in and copies its current value to a buffer that you supply.
The following program uses **DosScanEnv** to display the value of the environment variable specified in the command
line:
#define INCL_DOSQUEUES
#include <os2 .h>
main( )
{
SEL selEnvironment;
USHORT offCommand;
PSZ pszCommandLine;
PSZ pszValue;
USHORT cbWritten;
USHORT i , cch;
DosGetEnv(&selEnvironment, &offCommand);
pszCommandLine = MAKEP(selEnvironment, offCommand);
for (i = 0 ; pszCommandLine[i); i++);
for (i++; pszCommandLine[i] == ' '; i++);
if (!DosScanEnv (&pszCommandLine[i), &pszValue)) {
for (cch = 0; pszValue[cch); cch++);
DosWrite(1, pszValue, cch, &cbWritten);
}
}
### 2.5 Using the MS OS/2 Naming Conventions
The sample programs in this manual use the MS OS/2 naming conventions for their variables and functions.
These conventions define how to create names that indicate both the purpose and data type of an item used
with the MS OS/2 system functions. When you use the conventions in your source files, you help others
who may read your sources to readily identify the purpose and type of the functions, variables, structures, fields,
and constants.
The following list briefly describes the MS OS/2 naming conventions:
**Item** | **Convention**
:----------------- | :-------------
Variable | All names consist of three elements: a prefix, a base type, and a qualifier.
| The base type identifies the data type of the item; the prefix specifies additional
| information, such as whether the item is a pointer, an array, or a count of
| bytes; and the qualifier specifies the purpose of the item. The prefix and base
| type are lowercase, and the qualifier is mixed-case.
|
Parameter | Same as a variable.
|
Structure Field | Same as a variable.
|
Structure | All names consist of a word or phrase that specifies the purpose of the structure.
| All letters in the name are uppercase.
|
Constant | All names consist of a prefix, derived from the name of the function associated with
| the constant, and a word or phrase that specifies the meaning of the constant in terms
| of a value, action, color, or condition. All letters in the name are uppercase and an
| underscore separates the prefix from the rest of the name.
|
Function name | All names consist of a three-letter system prefix followed by a word or phrase that
| describes the action of the function. Each word in the function name starts with an
| uppercase letter. Verb-noun combinations, such as **DosGetDateTime**, are recommended.
|
The following examples show some of the standard prefix and base types you will see in this manual:
/* Base Types */
BOOL fSuccess; /* f Boolean flag. TRUE if successful */
CHAR chChar; /* ch 8-bit character */
SHORT sRate; /* s 16-bit signed integer */
LONG lDistance; /* l 32-bit signed integer */
UCHAR uchScan; /* uch 8-bit unsigned character */
USHORT usHeight; /* us 16-bit unsigned integer */
ULONG ulWidth; /* ul 32-bit unsigned integer */
BYTE bAttribute; /* b 8-bit unsigned integer */
CHAR szName[]; /* sz zero-terminated array of characters */
BYTE fbMask; /* fb array of flags in a byte */
USHORT fsMask; /* fs array of flags in a short */
ULONG flMask; /* fl array of flags in a long */
SEL selSegment; /* sel 16-bit segment selector */
/* Prefixes */
PCH pchBuffer; /* p 32-bit far pointer to a given type */
NPCH npchBuffer; /* np 16-bit newr pointer to a given type */
CHAR achData[1]; /* a array of a given type */
USHORT ichIndex; /* i index to an array of a given type */
USHORT cb; /* c count of items of a given type */
HFILE hf; /* hf handle identifying a given object */
USHORT offSeg; /* off offset */
USHORT idSession; /* id identifier for a given object */
When you are naming variables, remember that the prefix and base type are optional for common integer
types such as **SHORT** and **USHORT**.
### 2.6 Using Structures: Getting the Time of Day
Many MS OS/2 functions use structures for input and output parameters. To use a structure in an MS OS/2
function, you first define the structure in your program, then pass a 32-bit far address to the structure
as a parameter in the function call.
For example, the **DosGetDateTime** function copies the current date and time to a **DATETIME** structure
whose address you supply. The fields of the **DATETIME** structure define the month, day, and year, as well as
the time of day (to hundredths of a second). The **DATETIME** structure, defined in the *os2.h* file, has the
following form:
typedef struct _DATETIME { /* date */
UCHAR hours;
UCHAR minutes;
UCHAR seconds;
UCHAR hundredths;
UCHAR day;
UCHAR month;
USHORT year;
SHORT timezone;
UCHAR weekday;
} DATETIME;
To retrieve the date and time, you call the **DosGetDateTime** function and use the address operator (&) to
specify the address of your **DATETIME** structure in the call. The following example shows how to make the call:
#include <os2.h>
CHAR szDayName[] = "MonTueWedThuFriSatSun";
CHAR szMonthName[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
CHAR szDate[] = "xx:xx:xx xxx xxx xx, xxxx\r\n";
main( )
{
DATETIME date;
SHORT offset;
SHORT i;
USHORT usYear;
USHORT cbWritten;
DosGetDateTime(&date); /* Address of the DATETIME structure */
szDate[0] = (date.hours/10) + '0';
szDate[1] = (date.hours%10) + '0';
szDate[3] = (date.minutes/10) + '0';
szDate[4] = (date.minutes%10) + '0';
szDate[6] = (date.seconds/10) + '0';
szDate[7] = (date.seconds/10) + '0';
offset = date.weekday * 3;
for (i = 0; i < 3; i++)
szData[i + 9] = szDayName[i + offset];
offset = (date.month - 1) * 3;
for (i = 0; i < 3; i++)
szDate[i + 13] = szMonthName[i + offset];
szDate[17] = (date.day < 10)?' ':(date.day/10 + '0');
szDate[18] = (date.day%10) + '0';
usYear = date.year;
szDate[21] = (usYear/1000) + '0';
usYear = usYear % 1000;
szDate[22] = (usYear/100) + '0';
usYear = usYear % 100;
szDate[23] = (usYear/10) + '0';
szDate[24] = (usYear%10) + '0';
DosWrite(1, szDate, 27, &cbWritten);
}
One drawback of using MS OS/2 functions exclusively is that there are no formatted output functions,
such as the **printf** function. This sample program, therefore, formats the data itself before displaying it.
The program uses the integer-division operators (/ and %) to convert binary numbers to ASCII characters.
The program then copies the ASCII characters to a string and displays the string by using the **DosWrite** function.
Some MS OS/2 functions require that you fill one or more fields of the structure before making the function call.
For example, there are some structures whose length depends on the version of the operating system being used;
MS OS/2 requires that you supply the expected length so that the function does not copy data beyond the end of your
structure.
### 2.7 Using Bit Masks
In MS OS/2, many functions use bit masks. A bit mask (also called an array of flags) is a combination of two
or more Boolean flags in a single byte, word, or double-word value. In C-language programs, you can use the
bitwise AND, OR, and NOT operators to examine and set the values in a bit mask.
If a function retrieves a bit mask, you can check a specific flag in the bit mask by using the AND operator,
as shown in the following example:
USHORT fsEvents;
if (fsEvent & 0x0004)
/* Is the flag set */
Or you can set a flag in a bit mask by using the OR operator, as shown in the following example:
ULONG flFunctions;
flFunctions = flFunctions | KR_KBDPEEK;
Finally, you can clear a flag in a bit mask by using the AND and NOT operators, as shown in the following example:
USHORT fsEvent;
fsEvents = fsEvent & ~0x0004;
### 2.8 Sharing Resources: Playing a Tune
Many MS OS/2 functions let you use the resources of the computer, such as the keyboard, screen, disk, and even
the system speaker. Since MS OS/2 is a multitasking operating system and more than one program can run at a time,
MS OS/2 considers all resources of the computer to be shared resources. As a result, programs must cooperate with
other running programs and must not claim exclusive access to a given resource.
Consider a simple program that plays a short tune by using the **DosBeep** function. This function, when called
by a single program, generates a tone at the system speaker, but if two programs call **DosBeep** at the same time,
the result is chaos. Try running two or more copies of the following program at the same time:
#include <os2.h>
#define CNOTES 14
USHORT ausTune[] = {
440,1000,
480,1000,
510,1000,
550,1000,
590,1000,
620,1000,
660,1000
};
main( )
{
int i;
for (i = 0; i < CNOTES; i+= 2)
DosBeep(ausTune[i] , ausTune[i + 1]);
}
The first argument to the **DosBeep** function specifies the frequency of the note. The second argument specifies
the duration. The array ausTune defines values for the frequency and duration of each note in the tune.
**DosBeep** is intended to be used for signaling the user when an error occurs, such as pressing an incorrect key.
Since the system speaker is a shared resource, a process should use the **DosBeep** function sparingly.

View file

@ -0,0 +1,148 @@
---
layout: page
title: "Microsoft OS/2 Programmer's Learning Guide: Input and Output"
permalink: /pubs/pc/software/os2/microsoft/ptk10/plguide/chapter3/
---
[Microsoft OS/2 Programmer's Learning Guide](../)
---
Input and Output
---
### 3.1 Introduction
Input and output are two of the most important tasks that any program carries out. This chapter explains how
to read from and write to files on disks and other input and output devices, such as printers, modems, and the
system console.
### 3.2 Opening Files
Before carrying out any input or output operation, you need a file handle. A file handle is a 16-bit value
that identifies the file or device that you want to read from or write to. You can create a file handle by using
the **DosOpen** function, which opens the specified file and returns a file handle for it. For example, in the
following statements, **DosOpen** opens the existing file *simple.txt* for reading and copies the file handle to the
*hf* variable:
HFILE hf;
USHORT usResult;
DosOpen("simple.txt", /* filename */
&hf, /* file handle */
&usResult, /* action taken */
0, /* size */
0, /* file attribute */
0x0001, /* open method */
0x0040, /* access and sharing method */
0); /* reserved */
If the **DosOpen** function opens the file, it copies the file handle to the *hf* variable and copies a value to
the *usResult* variable to indicate what action was taken (for example, 0x0001 for "existing file opened"). To open
an existing file, a size and file attribute are not needed, so the fourth and fifth arguments are set to zero.
The sixth argument, 0x0001, directs **DosOpen** to open the file if it exists or to return an error if it does not
exist. The next argument, 0x0040, directs **DosOpen** to open the file for reading only and let other programs open
the file even while the current program has it open. The final argument is reserved and should always be zero.
The **DosOpen** function indicates that it successfully opened the file by returning zero. You can then use the file
handle returned in the *hf* variable in subsequent functions to read data from the file or to check the status or
other characteristics of the file. If **DosOpen** fails to open the file, it returns an error value. For example,
if the file cannot be found in the current directory, the function returns the value 0x0002.
When you open a file, you must specify whether you want to read from the file, write to it, or both read and write.
You must also specify whether you want other processes to have access to the file while you have it open. You do this
by combining two values. These values specify the access and sharing methods and are described in the following list:
**Value** | **Meaning**
:----------------- | :-------------
0x0000 | Open a file for reading.
0x0001 | Open a file for writing.
0x0002 | Open a file for reading and writing.
0x0010 | Open a file for exclusive use, denying read and write access by other processes.
0x0020 | Deny write access to a file by other processes.
0x0030 | Deny read access to a file by other processes.
0x0040 | Open a file with no sharing restrictions, granting read and write access to all processes.
|
In general, you may combine any access method (read, write, or read and write) with any sharing method
(deny reading, deny writing, deny reading and writing, or grant any access). Some combinations have to be
handled carefully, however, such as opening a file for writing without denying access to it by other processes.
### 3.3 Reading and Writing to Files
Once you have opened a file and have a file handle, you can read from or write to the file by using the
**DosRead** or **DosWrite** function. The **DosRead** function copies a specified number of bytes (up to the
end of the file) from the file to the buffer you specify. The **DosWrite** function copies bytes from a buffer
to the file.
To read from a file, you must open it for reading, or reading and writing. The following example shows how to
open the file named *sample.txt* and read the first 512 bytes from it:
HFILE hf;
USHORT usResult;
BYTE abBuffer[512];
USHORT cbRead;
if (!DosOpen("sample.txt", &hf, &usResult, 0, 0,
0x0001, 0x0040, 0)) {
DosRead(hf, abBuffer, 512, &cbRead);
DosClose(hf);
}
If the file does not have 512 bytes, **DosRead** reads up to the end of the file and copies the number of bytes
read to the *cbRead* variable. If the function has already read to the end of the file and there are no more bytes
to read, it copies zero to the *cbRead* variable.
To write to a file, you must open it first for writing, or for reading and writing. The following example shows
how to open the file *sample.txt* again and write 512 bytes to it:
HFILE hf;
USHORT usResult;
BYTE abBuffer[512);
USHORT cbWritten;
if (!DosOpen("sample.txt", &hf, &usResult, 0, 0,
0x0011, 0x0041, 0)) {
DosWrite(hf, abBuffer, 512, &cbWritten);
DosClose(hf);
}
The **DosWrite** function writes the contents of the buffer to the file. If it fails to write 512 bytes
(for example, if the disk is full), the function copies the number of bytes written to the *cbWritten* variable.
### 3.4 Creating a File
You can also create new files by using the **DosOpen** function. Once you have created a new file, you may read
from or write to it just as you would with an existing file.
To create a new file, set the sixth parameter to the value 0x0010. The **DosOpen** function then creates the file
if it does not already exist. In the following example, the **DosOpen** function creates the file *newfile.txt*:
HFILE hf;
USHORT usResult;
DosOpen("newfile.txt", /* filename */
&hf, /* file handle */
&usResult, /* action taken */
0, /* size */
0x0000, /* normal file attribute */
0x0010, /* Creates the file if it does not exist */
0x0011, /* write access, share with none */
0);
In this example, **DosOpen** creates the file and opens it for writing. Note that the sharing method denies
any access to all processes, so no other process can open the file while it remains open. The new file is empty
(it contains no data).
When a new file is created, the attribute argument (fifth) specifies the file attribute. In the preceding example,
the attribute argument is 0x0000, so the file is created as a normal file. Other possible file attributes are
read­only and hidden, which correspond to the values 0x0001 or 0x0002, respectively.
The file attribute affects how other processes access the file. For example, if the file is read-only, no process
may open the file for writing. The one exception to this rule is that the process that creates the read-only file
may write to it immediately after creating it. After closing the file, however, the process may not open it for
writing again.
When a file is created, the size argument (fourth) specifies the original size of the new file. For example,
if 256 is specified, the new file is 256 bytes long. These 256 bytes, however, are undefined. It is up to the
program to write valid data to the file. In any case, no matter what size you specify, subsequent calls to the
**DosWrite** function copy data to the beginning of the file.