IoCreateFile function (wdm.h)
The IoCreateFile routine either causes a new file or directory to be created, or it opens an existing file, device, directory, or volume, giving the caller a handle for the file object.
NTSTATUS IoCreateFile( [out] PHANDLE FileHandle, [in] ACCESS_MASK DesiredAccess, [in] POBJECT_ATTRIBUTES ObjectAttributes, [out] PIO_STATUS_BLOCK IoStatusBlock, [in, optional] PLARGE_INTEGER AllocationSize, [in] ULONG FileAttributes, [in] ULONG ShareAccess, [in] ULONG Disposition, [in] ULONG CreateOptions, [in, optional] PVOID EaBuffer, [in] ULONG EaLength, [in] CREATE_FILE_TYPE CreateFileType, [in, optional] PVOID InternalParameters, [in] ULONG Options );
Pointer to a variable that receives the file handle if the call is successful. The driver must close the handle with ZwClose once the handle is no longer in use.
A bitmask of flags specifying the type of access to the file or directory that the caller requires. See the DesiredAccess parameter of IoCreateFileEx for more information about this parameter and for the list of flag values.
Pointer to an opaque OBJECT_ATTRIBUTES structure that is already initialized with InitializeObjectAttributes. See the ObjectAttributes parameter of IoCreateFileEx for more information and for a description of each structure member.
Pointer to an IO_STATUS_BLOCK structure that receives the final completion status and information about the requested operation. See the IoStatusBlock parameter of IoCreateFileEx.
[in, optional] AllocationSize
Optionally specifies the initial allocation size in bytes for the file. A nonzero value has no effect unless the file is being created, overwritten, or superseded.
Explicitly specified attributes are applied only when the file is created, superseded, or, in some cases, overwritten. By default, this value is FILE_ATTRIBUTE_NORMAL, which can be overridden by an ORed combination of one or more FILE_ATTRIBUTE_XXX flags, which are defined in Wdm.h. For a list of flags that can be used with IoCreateFile, see CreateFile.
Specifies the type of share access to the file that the caller requires, as zero or one, or a combination of the flags. See the ShareAccess parameter of IoCreateFileEx for more details and for the list of flags.
Specifies a value that determines the action to be taken, depending on whether the file already exists. See the Disposition parameter of IoCreateFileEx for the list of possible values.
Specifies the options to be applied when creating or opening the file. This parameter is a compatible combination of the flags listed and described in the CreateOptions parameter of IoCreateFileEx.
[in, optional] EaBuffer
For device and intermediate drivers, this parameter must be a NULL pointer.
For device and intermediate drivers, this parameter must be zero.
Drivers must set this parameter to CreateFileTypeNone.
[in, optional] InternalParameters
Drivers must set this parameter to NULL.
Specifies options to be used during the creation of the create request. See the Options parameter of IoCreateFileEx for the list of possible options.
IoCreateFile either returns STATUS_SUCCESS or an appropriate error status. NTSTATUS value. See the Return Value section of IoCreateFileEx for a list of possible return codes.
The IoCreateFileEx routine is similar to the IoCreateFile routine but provides greater functionality than the IoCreateFile routine, including access to extra create parameters (ECPs), device objects, and transaction information.
The handle obtained by IoCreateFile can be used by subsequent calls to manipulate data within the file or the file object's state or attributes.
There are two alternate ways to specify the name of the file to be created or opened with IoCreateFile:
As a fully qualified pathname, supplied in the ObjectName member of the input ObjectAttributes
As pathname relative to the directory file represented by the handle in the RootDirectory member of the input ObjectAttributes
Certain DesiredAccess flags and combinations of flags have the following effects:
For a caller to synchronize an I/O completion by waiting for the returned FileHandle, the SYNCHRONIZE flag must be set. Otherwise, a caller that is a device or intermediate driver must synchronize an I/O completion by using an event object.
If only the FILE_APPEND_DATA and SYNCHRONIZE flags are set, the caller can write only to the end of the file, and any offset information about writes to the file is ignored. However, the file will automatically be extended as necessary for this type of write operation.
Setting the FILE_WRITE_DATA flag for a file also allows writes beyond the end of the file to occur. The file is automatically extended for this type of write, as well.
If only the FILE_EXECUTE and SYNCHRONIZE flags are set, the caller cannot directly read or write any data in the file using the returned FileHandle: that is, all operations on the file occur through the system pager in response to instruction and data accesses. Device and intermediate drivers should not set the FILE_EXECUTE flag in DesiredAccess.
The ShareAccess parameter determines whether separate threads can access the same file, possibly simultaneously. Provided that both file openers have the privilege to access a file in the specified manner, the file can be successfully opened and shared. If the original caller of IoCreateFile does not specify FILE_SHARE_READ, FILE_SHARE_WRITE, or FILE_SHARE_DELETE, no other open operations can be performed on the file: that is, the original caller is given exclusive access to the file.
In order for a shared file to be successfully opened, the requested DesiredAccess to the file must be compatible with both the DesiredAccess and ShareAccess specifications of all preceding opens that have not yet been released with ZwClose. That is, the DesiredAccess specified to IoCreateFile for a given file must not conflict with the accesses that other openers of the file have disallowed.
The Disposition value FILE_SUPERSEDE requires that the caller have DELETE access to a existing file object. If so, a successful call to IoCreateFile with FILE_SUPERSEDE on an existing file effectively deletes that file, and then recreates it. This implies that, if the file has already been opened by another thread, it opened the file by specifying a ShareAccessparameter with the FILE_SHARE_DELETE flag set. Note that this type of disposition is consistent with the POSIX style of overwriting files.
The Disposition values FILE_OVERWRITE_IF and FILE_SUPERSEDE are similar. If IoCreateFile is called with a existing file and either of these Disposition values, the file will be replaced.
Overwriting a file is semantically equivalent to a supersede operation, except for the following:
The caller must have write access to the file, rather than delete access. This implies that, if the file has already been opened by another thread, it opened the file with the FILE_SHARE_WRITE flag set in the input ShareAccess.
The specified file attributes are logically ORed with those already on the file. This implies that, if the file has already been opened by another thread, a subsequent caller of IoCreateFile cannot disable existing FileAttributes flags but can enable additional flags for the same file.
The CreateOptions FILE_DIRECTORY_FILE value specifies that the file to be created or opened is a directory file. When a directory file is created, the file system creates an appropriate structure on the disk to represent an empty directory for that particular file system's on-disk structure. If this option was specified and the given file to be opened is not a directory file, or if the caller specified an inconsistent CreateOptions or Disposition value, the call to IoCreateFile will fail.
The CreateOptions FILE_NO_INTERMEDIATE_BUFFERING flag prevents the file system from performing any intermediate buffering on behalf of the caller. Specifying this value places certain restrictions on the caller's parameters to the ZwXxxFile routines, including the following:
Any optional ByteOffset passed to ZwReadFile or ZwWriteFile must be an integral of the sector size.
The Length passed to ZwReadFile or ZwWriteFile, must be an integral of the sector size. Note that specifying a read operation to a buffer whose length is exactly the sector size might result in a lesser number of significant bytes being transferred to that buffer if the end of the file was reached during the transfer.
Buffers must be aligned in accordance with the alignment requirement of the underlying device. This information can be obtained by calling IoCreateFile to get a handle for the file object that represents the physical device, and, then, calling ZwQueryInformationFile with that handle. For a list of the system FILE_XXX_ALIGNMENT values, see DEVICE_OBJECT.
Calls to ZwSetInformationFile with the FileInformationClass parameter set to FilePositionInformation must specify an offset that is an integral of the sector size.
The CreateOptions FILE_SYNCHRONOUS_IO_ALERT and FILE_SYNCHRONOUS_IO_NONALERT, which are mutually exclusive as their names suggest, specify that all I/O operations on the file are to be synchronous as long as they occur through the file object referred to by the returned FileHandle. All I/O on such a file is serialized across all threads using the returned handle. With either of these CreateOptions, the DesiredAccess SYNCHRONIZE flag must be set so that the I/O manager will use the file object as a synchronization object. With either of these CreateOptions set, the I/O manager maintains the "file position context" for the file object, an internal, current file position offset. This offset can be used in calls to ZwReadFile and ZwWriteFile. Its position also can be queried or set with ZwQueryInformationFile and ZwSetInformationFile.
If the CreateOptions FILE_OPEN_REPARSE_POINT flag is not specified and IoCreateFile attempts to open a file with a reparse point, normal reparse point processing occurs for the file. If, on the other hand, the FILE_OPEN_REPARSE_POINT flag is specified, normal reparse processing does not occur and IoCreateFile attempts to directly open the reparse point file. In either case, if the open operation was successful, IoCreateFile returns STATUS_SUCCESS; otherwise, the routine returns an NTSTATUS error code. IoCreateFile never returns STATUS_REPARSE.
The CreateOptions FILE_OPEN_REQUIRING_OPLOCK flag eliminates the time between when you open the file and request an oplock that could potentially enable a third party to open the file and get a sharing violation. An application can use the FILE_OPEN_REQUIRING_OPLOCK flag on IoCreateFile and then request any oplock. This ensures that an oplock owner will be notified of any later open request that causes a sharing violation.
In Windows 7, if other handles exist on the file when an application uses the FILE_OPEN_REQUIRING_OPLOCK flag, the create operation will fail with STATUS_OPLOCK_NOT_GRANTED. This restriction no longer exists starting with Windows 8.
If this create operation would break an oplock that already exists on the file, then setting the FILE_OPEN_REQUIRING_OPLOCK flag will cause the create operation to fail with STATUS_CANNOT_BREAK_OPLOCK. The existing oplock will not be broken by this create operation.
An application that uses the FILE_OPEN_REQUIRING_OPLOCK flag must request an oplock after this call succeeds, or all subsequent attempts to open the file will be blocked without the benefit of normal oplock processing. Similarly, if this call succeeds but the subsequent oplock request fails, an application that uses this flag must close its handle after it detects that the oplock request has failed.
The FILE_OPEN_REQUIRING_OPLOCK flag is available in Windows 7, Windows Server 2008 R2 and later versions of Windows. The Microsoft file systems that implement this flag in Windows 7 are NTFS, FAT, and exFAT.
The CreateOptions flag, FILE_RESERVE_OPFILTER, allows an application to request a level 1, batch, or filter oplock to prevent other applications from getting share violations. However, FILE_RESERVE_OPFILTER is only useful for filter oplocks. To use it, you must follow these steps:
Issue a create request with CreateOptions of FILE_RESERVE_OPFILTER, DesiredAccess of exactly FILE_READ_ATTRIBUTES, and ShareAccess of exactly FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
If there are already open handles, the create request fails with STATUS_OPLOCK_NOT_GRANTED, and the next requested oplock also fails.
If you open with more access or less sharing will also cause a failure of STATUS_OPLOCK_NOT_GRANTED.
If the create request succeeds, request an oplock.
Open another handle to the file to do I/O.
Step 3 makes this practical only for filter oplocks. The handle opened in step 3 can have a DesiredAccess that contains a maximum of FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNCHRONIZE | READ_CONTROL and still not break a filter oplock. However, any DesiredAccess greater than FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE will break a level 1 or batch oplock and make the FILE_RESERVE_OPFILTER flag useless for those oplock types.
The Options IO_NO_PARAMETER_CHECKING flag can be useful if a driver is issuing a kernel-mode create request on behalf of an operation initiated by a user-mode application. Because the request occurs within a user-mode context, the I/O manager, by default, probes the supplied parameter values, which can cause an access violation if the parameters are kernel-mode addresses. This flag enables the caller to override this default behavior and avoid the access violation.
For create requests originating in user mode, if the driver sets both IO_NO_PARAMETER_CHECKING and IO_FORCE_ACCESS_CHECK in the Options parameter of IoCreateFile then it should also set OBJ_FORCE_ACCESS_CHECK in the ObjectAttributes parameter. For info on this flag, see the Attributes member of OBJECT_ATTRIBUTES.
NTFS is the only Microsoft file system that implements FILE_RESERVE_OPFILTER.
Driver routines that run in a process context other than that of the system process must set the OBJ_KERNEL_HANDLE attribute for the ObjectAttributes parameter of IoCreateFile. This restricts the use of the handle returned by IoCreateFile to processes running only in kernel mode. Otherwise, the handle can be accessed by the process in whose context the driver is running. Drivers can call InitializeObjectAttributes to set the OBJ_KERNEL_HANDLE attribute as follows.
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
|Header||wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)|
|DDI compliance rules||HwStorPortProhibitedDDIs(storport), IrqlIoPassive4(wdm), PowerIrpDDis(wdm)|
IoCreateFileEx (DesiredAccess parameter)
Submit and view feedback for