File Creation Functions

This section details the various functions available in the Windows API for creating files. These functions provide granular control over file creation, allowing you to specify attributes, security descriptors, and other crucial parameters.

Overview

Creating a file is a fundamental operation in Windows programming. The choice of function depends on factors such as the desired level of control over file attributes, security settings, and whether you need to support Unicode or ANSI character sets.

Core Functions

CreateFile

This is the primary function for opening or creating a file or I/O device. It offers a comprehensive set of parameters to control access, sharing, security, and file attributes.

Syntax:

HANDLE CreateFile(
    LPCTSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile
);

Key Parameters:

  • lpFileName: The name of the file or device.
  • dwDesiredAccess: The requested access to the file.
  • dwShareMode: How the file can be shared.
  • dwCreationDisposition: Action to take if the file exists or not.
  • dwFlagsAndAttributes: File attributes and flags.

Return Value: A handle to the opened file or device, or INVALID_HANDLE_VALUE on failure.

See Also: CreateFile2

CreateFileTransacted

This function creates or opens a file with transactional support. It allows file operations to be part of a transaction, enabling atomicity for file modifications.

Syntax:

HANDLE CreateFileTransacted(
    LPCTSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile,
    HANDLE hTransaction
);

Key Parameters:

  • hTransaction: A handle to the transaction.

Return Value: A handle to the opened file or device, or INVALID_HANDLE_VALUE on failure.

Note: Requires the Transactional NTFS (TxF) file system.

CreateFile2

An enhanced version of CreateFile that provides more control and flexibility, especially for modern Windows versions. It uses a structure to pass parameters, making it easier to extend in the future.

Syntax:

HANDLE CreateFile2(
    PCWSTR                             pcwszFileName,
    DWORD                              dwDesiredAccess,
    DWORD                              dwShareMode,
    DWORD                              dwCreationDisposition,
    const CREATEFILE2_EXTENDED_PARAMETERS *pCreateExParams
);

Key Parameters:

  • pcwszFileName: A pointer to a null-terminated Unicode string that specifies the name of the file or device.
  • pCreateExParams: A pointer to a CREATEFILE2_EXTENDED_PARAMETERS structure that contains extended parameters for the operation. This structure allows for specifying more attributes and options than CreateFile.

Return Value: A handle to the opened file or device, or INVALID_HANDLE_VALUE on failure.

Advantages: Supports Unicode strings directly, more extensible parameter set.

Important Note: When creating files, always consider security implications. Properly set the lpSecurityAttributes parameter to define the access control lists (ACLs) for the new file. Failure to do so might result in overly permissive access.

Common Scenarios and Usage

Creating a New File (and overwriting if it exists)

You can use CreateFile with CREATE_ALWAYS to create a new file or overwrite an existing one.

HANDLE hFile = CreateFile(
    L"my_new_file.txt",             // File name
    GENERIC_WRITE,                  // Desired access
    0,                              // Share mode (no sharing)
    NULL,                           // Security attributes (default)
    CREATE_ALWAYS,                  // Creation disposition
    FILE_ATTRIBUTE_NORMAL,          // File attributes
    NULL                            // Template file
);

if (hFile == INVALID_HANDLE_VALUE) {
    // Handle error
    DWORD error = GetLastError();
    // ...
} else {
    // File created or opened successfully. Write data here.
    CloseHandle(hFile); // Close the handle when done
}

Creating a New File (only if it doesn't exist)

Use CREATE_NEW to ensure you only create a file if it does not already exist. If it exists, the function will fail.

HANDLE hFile = CreateFile(
    L"unique_data.dat",
    GENERIC_WRITE,
    0,
    NULL,
    CREATE_NEW,
    FILE_ATTRIBUTE_NORMAL,
    NULL
);

if (hFile == INVALID_HANDLE_VALUE) {
    DWORD error = GetLastError();
    if (error == ERROR_ALREADY_EXISTS) {
        // File already exists, handle appropriately
    } else {
        // Handle other errors
    }
} else {
    // File created successfully
    CloseHandle(hFile);
}