The Windows File Management 4

 

 

 

 

 

Creating and Opening Files

 

The CreateFile() function can create a new file or open an existing file. You must specify the file name, creation instructions, and other attributes. When an application creates a new file, the operating system adds it to the specified directory. The operating system assigns a unique identifier, called a handle, to each file that is opened or created using CreateFile(). An application can use this handle with functions that read from, write to, and describe the file. It is valid until all references to that handle are closed. When an application starts, it inherits all open handles from the process that started it if the handles were created as inheritable. An application should check the value of the handle returned by CreateFile() before attempting to use the handle to access the file. If an error occurs, the handle value will be INVALID_HANDLE_VALUE and the application can use the GetLastError() function for extended error information.

When an application uses CreateFile(), it must use the dwDesiredAccess parameter to specify whether it intends to read from the file, write to the file, both read and write, or neither. This is known as requesting an access mode. The application must also use the dwCreationDisposition parameter to specify what action to take if the file already exists, known as the creation disposition. For example, an application can call CreateFile() with dwCreationDisposition set to CREATE_ALWAYS to always create a new file, even if a file of the same name already exists (thus overwriting the existing file). Whether this succeeds or not depends on factors such as the previous file's attributes and security settings (see the following sections for more information). An application also uses CreateFile() to specify whether it wants to share the file for reading, writing, both, or neither. This is known as the sharing mode. An open file that is not shared (dwShareMode set to zero) cannot be opened again, either by the application that opened it or by another application, until its handle has been closed. This is also referred to as exclusive access.

When a process uses CreateFile() to attempt to open a file that has already been opened in a sharing mode (dwShareMode set to a valid non-zero value), the system compares the requested access and sharing modes to those specified when the file was opened. If you specify an access or sharing mode that conflicts with the modes specified in the previous call, CreateFile() fails. The following table illustrates the valid combinations of two calls to CreateFile() using various access modes and sharing modes (dwDesiredAccess, dwShareMode respectively). It does not matter in which order the CreateFile() calls are made. However, any subsequent file I/O operations on each file handle will still be constrained by the current access and sharing modes associated with that particular file handle.

 

First call to CreateFile()

Valid second calls to CreateFile()

GENERIC_READ, FILE_SHARE_READ

GENERIC_READ, FILE_SHARE_READ

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_READ

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ

GENERIC_READ, FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE

 

In addition to the standard file attributes, you can also specify security attributes by including a pointer to a SECURITY_ATTRIBUTES structure as the fourth parameter of CreateFile(). However, the underlying file system must support security for this to have any effect (for example, the NTFS file system supports it but the various FAT file systems do not). An application creating a new file can supply an optional handle to a template file, from which CreateFile() takes file attributes and extended attributes for creation of the new file.

 

CreateFile() Scenarios

 

There are several fundamental scenarios for initiating access to a file using the CreateFile() function. These are summarized as:

  1. Creating a new file when a file with that name does not already exist.
  2. Creating a new file even if a file of the same name already exists, clearing its data and starting empty.
  3. Opening an existing file only if it exists, and only intact.
  4. Opening an existing file only if it exists, truncating it to be empty.
  5. Opening a file always: as-is if it exists, creating a new one if it doesn't exist.

 

These scenarios are controlled by the proper use of the dwCreationDisposition parameter. Below is a breakdown of how these scenarios map to values for this parameter and what happens when they are used. When creating or opening a new file when a file with that name does not already exist (dwCreationDisposition set to either CREATE_NEW, CREATE_ALWAYS, or OPEN_ALWAYS), the CreateFile() function performs the following actions:

  1. Combines the file attributes and flags specified by dwFlagsAndAttributes with FILE_ATTRIBUTE_ARCHIVE.
  2. Sets the file length to zero.
  3. Copies the extended attributes supplied by the template file to the new file if the hTemplateFile parameter is specified (this overrides all FILE_ATTRIBUTE_* flags specified earlier).
  4. Sets the inherit flag specified by the bInheritHandle member and the security descriptor specified by the lpSecurityDescriptor member of the lpSecurityAttributes parameter (SECURITY_ATTRIBUTES structure), if supplied.

 

When creating a new file even if a file of the same name already exists (dwCreationDisposition set to CREATE_ALWAYS), the CreateFile() function performs the following actions:

  1. Checks current file attributes and security settings for write access, failing if denied.
  2. Combines the file attributes and flags specified by dwFlagsAndAttributes with FILE_ATTRIBUTE_ARCHIVE and the existing file attributes.
  3. Sets the file length to zero (that is, any data that was in the file is no longer available and the file is empty).
  4. Copies the extended attributes supplied by the template file to the new file if the hTemplateFile parameter is specified (this overrides all FILE_ATTRIBUTE_* flags specified earlier).
  5. Sets the inherit flag specified by the bInheritHandle member of the lpSecurityAttributes parameter (SECURITY_ATTRIBUTES structure) if supplied, but ignores the lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure.
  6. If otherwise successful (that is, CreateFile() returns a valid handle), calling GetLastError() will yield the code ERROR_ALREADY_EXISTS, even though for this particular use-case it is not actually an error as such (if you intended to create a "new" (empty) file in place of the existing one).

 

When opening an existing file (dwCreationDisposition set to either OPEN_EXISTING, OPEN_ALWAYS, or TRUNCATE_EXISTING), the CreateFile() function performs the following actions:

  1. Checks current file attributes and security settings for requested access, failing if denied.
  2. Combines the file flags (FILE_FLAG_*) specified by dwFlagsAndAttributes with existing file attributes, and ignores any file attributes (FILE_ATTRIBUTE_*) specified by dwFlagsAndAttributes.
  3. Sets the file length to zero only if dwCreationDisposition is set to TRUNCATE_EXISTING, otherwise the current file length is maintained and the file is opened as-is.
  4. Ignores the hTemplateFile parameter.
  5. Sets the inherit flag specified by the bInheritHandle member of the lpSecurityAttributes parameter (SECURITY_ATTRIBUTES structure) if supplied, but ignores the lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure.

 

 

 

 

< Windows Files 3 | Win32 Programming | Win32 File Index | Windows Files 5 >