NtCreateFile 函数 (winternl.h)

创建新文件或目录,或打开现有文件、设备、目录或卷。

此函数是与 Windows 驱动程序工具包(WDK)中记录的 ZwCreateFile 函数等效的用户模式。

语法

__kernel_entry NTSTATUS NtCreateFile(
  [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              CreateDisposition,
  [in]           ULONG              CreateOptions,
  [in]           PVOID              EaBuffer,
  [in]           ULONG              EaLength
);

参数

[out] FileHandle

指向在调用成功时接收文件句柄的变量的指针。

[in] DesiredAccess

表示调用方对文件或目录所需的访问类型的 ACCESS_MASK 值。 一组系统定义的 DesiredAccess 标志决定了文件对象的以下特定访问权限。

价值 意义
DELETE
可以删除该文件。
FILE_READ_DATA
可以从文件读取数据。
FILE_READ_ATTRIBUTES
FileAttributes 标志(稍后介绍)可以读取。
FILE_READ_EA
可以读取与文件关联的扩展属性。 此标志与设备和中间驱动程序无关。
READ_CONTROL
可以读取与文件关联的访问控制列表(ACL)和所有权信息。
FILE_WRITE_DATA
可将数据写入文件。
FILE_WRITE_ATTRIBUTES
FileAttributes 标志可以写入。
FILE_WRITE_EA
可以编写与文件关联的扩展属性(EA)。 此标志与设备和中间驱动程序无关。
FILE_APPEND_DATA
可将数据追加到文件。
WRITE_DAC
可以编写与文件关联的自由访问控制列表(DACL)。
WRITE_OWNER
可以编写与文件关联的所有权信息。
SYNCHRONIZE
返回的 FileHandle 可以等待与 I/O 操作完成同步。 如果未为同步 I/O 打开 FileHandle,则忽略此值。
FILE_EXECUTE
可以使用系统分页 I/O 将数据读入文件中的内存。 此标志与设备和中间驱动程序无关。
  创建或打开目录时,请勿指定 FILE_READ_DATAFILE_WRITE_DATAFILE_APPEND_DATAFILE_EXECUTE

NtCreateFile 的调用方可以为不表示目录文件的任何文件对象指定一个或组合,可能对上述 DesiredAccess 标志列表使用按位或附加兼容标志。

价值 意义
FILE_GENERIC_READ
STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE
FILE_GENERIC_WRITE
STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
FILE_GENERIC_EXECUTE
STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE

FILE_GENERIC_EXECUTE 值与设备和中间驱动程序无关。

STANDARD_RIGHTS_XXX 是预定义的系统值,用于对系统对象强制执行安全性。

若要打开或创建目录文件,如 CreateOptions 参数所示,NtCreateFile 的调用方可以指定以下的一个或多个兼容标志,可能对上述 DesiredAccess 标志列表使用按位或组合。

价值 意义
FILE_LIST_DIRECTORY
可以列出目录中的文件。
FILE_TRAVERSE
可以遍历目录:也就是说,它可以是文件路径名的一部分。

[in] ObjectAttributes

指向已使用 InitializeObjectAttributes初始化的结构的指针。 文件对象的此结构的成员包括以下内容。

价值 意义
ULONG 长度
指定提供的 ObjectAttributes 数据的字节数。 此值必须至少为 sizeof(OBJECT_ATTRIBUTES)。
HANDLE RootDirectory
(可选)指定上一次调用 ntCreateFile获取的目录的句柄。 如果此值 NULL,则 ObjectName 成员必须是包含目标文件的完整路径的完全限定文件规范。 如果此值为非NULL,则 ObjectName 成员指定相对于此目录的文件名。
PUNICODE_STRING ObjectName
指向用于命名要创建或打开的文件的缓冲 Unicode 字符串。 此值必须是完全限定的文件规范或设备对象的名称,除非它是相对于 RootDirectory指定的目录的文件的名称。 例如,\Device\Floppy1\myfile.dat 或 \??\B:\myfile.dat可能是完全限定的文件规范,前提是已加载软盘驱动程序和过度文件系统。 有关详细信息,请参阅 文件名、路径和命名空间
ULONG 属性
一组用于控制文件对象属性的标志。 此值可以是零或 OBJ_CASE_INSENSITIVE,指示名称查找代码应忽略 ObjectName 成员的情况,而不是执行完全匹配的搜索。 值 OBJ_INHERIT 与设备和中间驱动程序无关。
PSECURITY_DESCRIPTOR SecurityDescriptor
(可选)指定要应用于文件的安全描述符。 此类安全描述符指定的 ACL 仅在创建文件时应用于该文件。 如果在创建文件时 NULL 值,则文件上放置的 ACL 依赖于文件系统;大多数文件系统从父目录文件传播此类 ACL 的某些部分,并结合调用方的默认 ACL。 设备和中间驱动程序可以将此成员设置为 NULL
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService
指定应向客户端的安全上下文提供服务器的访问权限。 仅当建立与受保护服务器的连接时,此值为非NULL,允许调用方控制调用方的安全上下文中哪些部分可供服务器使用,以及是否允许服务器模拟调用方。

[out] IoStatusBlock

指向接收最终完成状态的变量的指针,以及有关请求的操作的信息。 从 NtCreateFile返回时,信息 成员包含以下值之一:

  • FILE_CREATED
  • FILE_OPENED
  • FILE_OVERWRITTEN
  • FILE_SUPERSEDED
  • FILE_EXISTS
  • FILE_DOES_NOT_EXIST

[in, optional] AllocationSize

文件的初始分配大小(以字节为单位)。 除非正在创建、覆盖或取代文件,否则非零值不起作用。

[in] FileAttributes

文件属性。 仅当文件创建、取代或在某些情况下覆盖文件时,才会应用显式指定的属性。 默认情况下,此值是一个 FILE_ATTRIBUTE_NORMAL,可通过一个或多个 FILE_ATTRIBUTE_xxxx 标志(在 Wdm.h 和 NtDdk.h 中定义)的 ORed 组合重写该值。 有关可与 NtCreateFile一起使用的标志列表,请参阅 CreateFile

[in] ShareAccess

调用方想要在文件中使用的共享访问类型,为零,或用作以下值的一个或多个组合。

价值 意义
FILE_SHARE_READ
可以通过其他线程调用 NtCreateFile打开该文件进行读取访问。
FILE_SHARE_WRITE
可以通过其他线程调用 NtCreateFile来打开该文件进行写入访问。
FILE_SHARE_DELETE
可以通过其他线程调用 NtCreateFile打开该文件以删除访问权限。

有关详细信息,请参阅 Windows SDK。

[in] CreateDisposition

指定要执行的操作,具体取决于文件是否已存在,作为以下值之一。

价值 意义
FILE_SUPERSEDE
如果文件已存在,请将其替换为给定的文件。 如果没有,请创建给定的文件。
FILE_CREATE
如果文件已存在,则请求失败,并且不创建或打开给定文件。 如果没有,请创建给定的文件。
FILE_OPEN
如果文件已存在,请将其打开,而不是创建新文件。 如果没有,则失败请求,并且不创建新文件。
FILE_OPEN_IF
如果文件已存在,请将其打开。 如果没有,请创建给定的文件。
FILE_OVERWRITE
如果文件已存在,请将其打开并覆盖它。 否则,请求失败。
FILE_OVERWRITE_IF
如果文件已存在,请将其打开并覆盖它。 如果没有,请创建给定的文件。

[in] CreateOptions

创建或打开文件时要应用的选项,作为以下标志的兼容组合。

价值 意义
FILE_DIRECTORY_FILE
正在创建或打开的文件是目录文件。 使用此标志,必须将 CreateDisposition 参数设置为 FILE_CREATEFILE_OPENFILE_OPEN_IF。 使用此标志时,其他兼容 CreateOptions 标志仅包含以下项:FILE_SYNCHRONOUS_IO_ALERTFILE_SYNCHRONOUS_IO _NONALERTFILE_WRITE_THROUGHFILE_OPEN_FOR_BACKUP_INTENTFILE_OPEN_BY_FILE_ID
FILE_NON_DIRECTORY_FILE
打开的文件不能是目录文件,否则此调用将失败。 要打开的文件对象可以表示数据文件、逻辑、虚拟或物理设备或卷。
FILE_WRITE_THROUGH
将数据写入文件的应用程序必须在任何请求的写入操作被视为完成之前实际将数据传输到文件中。 如果设置了 CreateOptions 标志 FILE_NO_INTERMEDIATE _BUFFERING,则会自动设置此标志。
FILE_SEQUENTIAL_ONLY
对文件的所有访问都是顺序的。
FILE_RANDOM_ACCESS
对文件的访问权限可以是随机的,因此 FSD 或系统不应对文件执行顺序预读操作。
FILE_NO_INTERMEDIATE_BUFFERING
文件不能缓存或缓冲在驱动程序的内部缓冲区中。 此标志与 DesiredAccessFILE_APPEND_DATA 标志不兼容。
FILE_SYNCHRONOUS_IO_ALERT
对文件执行的所有操作都是同步执行的。 代表调用方的任何等待都受到警报的过早终止。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccessSYNCHRONIZE 标志。
FILE_SYNCHRONOUS_IO_NONALERT
对文件执行的所有操作都是同步执行的。 系统等待同步 I/O 队列和完成不受警报约束。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccessSYNCHRONIZE 标志。
FILE_CREATE_TREE_CONNECTION
为此文件创建树连接,以便通过网络将其打开。 设备和中间驱动程序不使用此标志。
FILE_NO_EA_KNOWLEDGE
如果打开现有文件上的扩展属性表示调用方必须了解 EA 才能正确解释文件,则失败此请求,因为调用方不了解如何处理 EA。 此标志与设备和中间驱动程序无关。
FILE_OPEN_REPARSE_POINT
使用重新分析点打开文件,并绕过文件的正常重新分析点处理。 有关详细信息,请参阅“备注”部分。
FILE_DELETE_ON_CLOSE
将最后一个句柄传递给 NtClose时,请删除该文件。 如果设置了此标志,则必须在 DesiredAccess 参数中设置 DELETE 标志。
FILE_OPEN_BY_FILE_ID
ObjectAttributes 参数指定的文件名包括文件的 8 字节文件引用号。 此数字由特定文件系统分配并特定于特定文件系统。 如果文件是重新分析点,则文件名还将包含设备的名称。 请注意,FAT 文件系统不支持此标志。 设备和中间驱动程序不使用此标志。
FILE_OPEN_FOR_BACKUP_INTENT
文件正在打开以供备份意向使用。 因此,系统应检查某些访问权限,并在根据文件的安全描述符检查 DesiredAccess 参数之前,向调用方授予对该文件的适当访问权限。 设备和中间驱动程序不使用此标志。
FILE_RESERVE_OPFILTER
此标志允许应用程序请求筛选器机会锁([机会锁](/windows/win32/fileio/机会主义锁)以防止其他应用程序收到共享冲突。 如果已打开句柄,则创建请求将失败并 STATUS_OPLOCK_NOT_GRANTED。 有关详细信息,请参阅“备注”部分。
FILE_OPEN_REQUIRING_OPLOCK
文件正在打开,文件上的机会锁([机会锁](/windows/win32/fileio/机会主义锁)正在请求为单个原子操作。 文件系统在执行创建操作之前检查操作是否为 oplock,如果结果将中断现有 oplock,则使用返回代码 STATUS_CANNOT_BREAK_OPLOCK 创建失败。 有关详细信息,请参阅“备注”部分。Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:不支持 此标志。

以下文件系统支持此标志:NTFS、FAT 和 exFAT。

FILE_COMPLETE_IF_OPLOCKED
如果目标文件处于操作锁定状态,而不是阻止调用方线程,请立即使用 STATUS_OPLOCK_BREAK_IN_PROGRESS 备用成功代码完成此操作。 如果文件是 oplocked ([机会锁](/windows/win32/fileio/机会主义-locks),另一个调用方已经有权访问该文件。 设备和中间驱动程序不使用此标志。

[in] EaBuffer

指向用于传递扩展属性的 EA 缓冲区的指针。

注意 某些文件系统可能不支持 EA 缓冲区。
 

[in] EaLength

EA 缓冲区的长度。

返回值

NtCreateFile 返回 STATUS_SUCCESS 或适当的错误状态。 如果返回错误状态,调用方可以通过检查 IoStatusBlock来查找有关失败原因的详细信息。 为了简化此检查,应用程序可以使用 NT_SUCCESSNT_ERRORNT_WARNING 宏。

言论

NtCreateFile提供的句柄可由后续调用用来操作文件或文件对象的状态或属性中的数据。

可通过两种替代方法指定要创建或打开的文件的名称,NtCreateFile

  • 作为完全限定的路径名,在输入 ObjectAttributesObjectName 成员中提供
  • 作为路径名称,相对于由输入 ObjectAttributesRootDirectory 成员中的句柄表示的目录文件

某些 DesiredAccess 标志和标志的组合具有以下效果:

  • 若要使调用方通过等待返回的 FileHandle来同步 I/O 完成,必须设置 SYNCHRONIZE 标志。
  • 将零传递给 DesiredFlags 无效。
  • 如果仅设置了 FILE_APPEND_DATASYNCHRONIZE 标志,则调用方只能写入文件末尾,并且忽略对文件写入的任何偏移信息。 但是,根据这种类型的写入操作,文件会自动扩展。
  • 设置文件的 FILE_WRITE_DATA 标志还允许在文件末尾之外进行写入。 该文件也会自动扩展为这种类型的写入。
  • 如果仅设置了 FILE_EXECUTESYNCHRONIZE 标志,则调用方无法使用返回的 FileHandle直接读取或写入文件中的任何数据,也就是说,文件上的所有操作都通过系统寻呼器来响应指令和数据访问。

ShareAccess 参数确定单独的线程是否可以同时访问同一文件。 如果两个文件打开者都有权以指定方式访问文件,则可以成功打开和共享该文件。 如果 NtCreateFile 的原始调用方未指定 FILE_SHARE_READFILE_SHARE_WRITEFILE_SHARE_DELETE,则无法对文件执行其他打开操作;也就是说,原始调用方对文件具有独占访问权限。

若要成功打开共享文件,所请求的 DesiredAccess 参数必须与 DesiredAccessShareAccess 规范兼容,这些规范尚未随 NtClose一起发布。 也就是说,为给定文件的 NtCreateFile 指定的 DesiredAccess 参数不得与不允许文件的其他打开者访问冲突。

CreateDispositionFILE_SUPERSEDE 要求调用方具有对现有文件对象的 DELETE 访问权限。 如果是这样,则成功调用 NtCreateFile,并在现有文件上 FILE_SUPERSEDE 有效删除该文件,然后重新创建该文件。 这意味着,如果文件已被另一个线程打开,则它通过指定具有 FILE_SHARE_DELETE 标志集的 ShareAccess 参数来打开该文件。

请注意,这种类型的处置与覆盖文件的 POSIX 样式一致。 CreateDispositionFILE_OVERWRITE_IFFILE_SUPERSEDE 相似。 如果使用现有文件调用 ZwCreateFile ,并且其中任一 CreateDisposition 值,则会替换该文件。

覆盖文件在语义上等效于取代操作,但以下情况除外:

  • 调用方必须具有对文件的写入访问权限,而不是删除访问权限。 这意味着,如果文件已被另一个线程打开,则会打开该文件,并在输入 ShareAccess 参数中设置 FILE_SHARE_WRITE 标志。
  • 指定的文件属性在逻辑上为 ORed,该文件中已存在这些属性。 这意味着,如果文件已被另一个线程打开,则 NtCreateFile 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。 请注意,此覆盖文件的样式与 MS-DOS、Windows 3.1 和 OS/2 操作系统一致。

CreateOptionsFILE_DIRECTORY_FILE 值指定要创建或打开的文件是目录文件。 创建目录文件时,文件系统会在磁盘上创建适当的结构,以表示该特定文件系统磁盘结构中的空目录。 如果指定了此选项并且要打开的给定文件不是目录文件,或者调用方指定了不一致的 createOptionsCreateDisposition 值,则对 NtCreateFile 的调用将失败。

CreateOptionsFILE_NO_INTERMEDIATE_BUFFERING 标志阻止文件系统代表调用方执行任何中间缓冲。 指定此值会将调用方参数的某些限制置于其他 NtXXXFile 例程,包括:

  • 传递给 NtReadFileNtWriteFile 函数的任何可选 ByteOffset 必须是扇区大小的整型。
  • 传递给 NtReadFileNtWriteFile长度 必须是扇区大小的一个整数。 请注意,指定对缓冲区的读取操作(其长度正好是扇区大小)可能会导致在传输过程中到达文件的末尾时,将较少的有效字节传输到该缓冲区。
  • 必须根据基础设备的对齐要求调整缓冲区。 可以通过调用 NtCreateFile 获取此信息,以获取表示物理设备的文件对象的句柄,然后使用该句柄调用 NtQueryInformationFile。 有关系统 FILE_XXX_ALIGNMENT 值的列表,请参阅 Windows SDK 文档。
  • 调用 NtSetInformationFileFileInformationClass 参数设置为 FilePositionInformation 必须指定扇区大小的整型偏移量。
CreateOptionsFILE_SYNCHRONOUS_IO_ALERTFILE_SYNCHRONOUS_IO_NONALERT 标志(顾名思义,它们相互排斥)指定,只要通过返回 FileHandle引用的文件对象进行,文件上的所有 I/O 操作都是同步的。 此类文件上的所有 I/O 都使用返回的句柄在所有线程之间序列化。 使用上述任一 CreateOptions,必须设置 DesiredAccessSYNCHRONIZE 标志,以便 I/O 管理器将文件对象用作同步对象。 设置上述任一 CreateOptions 后,I/O 管理器将维护文件对象的“文件位置上下文”,这是内部的当前文件位置偏移量。 此偏移量可用于调用 NtReadFileNtWriteFile。 还可以使用 NtQueryInformationFile 查询或设置其位置,NtSetInformationFile

如果 CreateOptions 参数指定 FILE_OPEN_REPARSE_POINT 标志,NtCreateFile 打开具有重新分析点的文件,则不会进行正常的重新分析处理,NtCreateFile 尝试直接打开重新分析点文件。 如果未指定 FILE_OPEN_REPARSE_POINT 标志,则对文件进行正常的重新分析点处理。 在任一情况下,如果打开操作成功,NtCreateFile 返回 STATUS_SUCCESS;否则为错误代码。 NtCreateFile 函数永远不会返回 STATUS_REPARSE

CreateOptions 参数的 FILE_OPEN_REQUIRING_OPLOCK 标志消除了打开文件并请求可能允许第三方打开文件(这会导致共享冲突)之间的时间。 应用程序可以将 FILE_OPEN_REQUIRING_OPLOCK 标志与 NtCreateFile 一起使用,然后请求任何 oplock。 这可确保 oplock 所有者将收到导致共享冲突的任何后续打开请求的通知。

在 Windows 7 中,如果应用程序使用此标志时文件中存在其他句柄,则创建操作将失败并 STATUS_OPLOCK_NOT_GRANTED。 从 Windows 8 开始,此限制不再存在。

如果此创建操作会中断文件上已存在的 oplock,则设置 FILE_OPEN_REQUIRING_OPLOCK 标志将导致创建操作失败,并 STATUS_CANNOT_BREAK_OPLOCK。 此创建操作不会破坏现有 oplock。

使用此标志的应用程序必须在此调用成功后请求 oplock,否则将阻止打开文件的所有后续尝试,而无需正常操作锁处理。 同样,如果此调用成功但后续的 oplock 请求失败,则使用此标志的应用程序必须在检测到 oplock 请求失败后关闭其句柄。

注释 Windows 7、Windows Server 2008 R2 及更高版本的操作系统中提供了 FILE_OPEN_REQUIRING_OPLOCK 标志,适用于以下文件系统:NTFS、FAT 和 exFAT。
 

CreateOptions 参数的 FILE_RESERVE_OPFILTER 标志允许应用程序请求级别 1、Batch 或 Filter oplock,以防止其他应用程序出现共享冲突。 但是,在实际情况下,FILE_RESERVE_OPFILTER 仅适用于筛选器 oplock。 若要使用它,必须完成以下步骤:

  1. CreateOptionsFILE_RESERVE_OPFILTERDesiredAccess 完全 FILE_READ_ATTRIBUTES发出创建请求,完全 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)的 ShareAccess。 可能的失败如下:
    • 如果已打开句柄,则创建请求会失败并 STATUS_OPLOCK_NOT_GRANTED,并且下一个请求的 oplock 也会失败。
    • 如果打开的访问权限超过 FILE_READ_ATTRIBUTES 或共享小于 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),则请求将失败并 STATUS_OPLOCK_NOT_GRANTED
  2. 如果创建请求成功,请请求 oplock。
  3. 打开文件的另一个句柄以执行 I/O。
步骤 3 使此功能仅适用于筛选器 oplock。 在步骤 3 中打开的句柄可以有一个 DesiredAccess,其中包含最多 (FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNCHRONIZE | READ_CONTROL),并且仍然不会中断筛选器操作锁。 但是,任何大于 的 DesiredAccess 都会中断级别 1 或 Batch oplock,并使 FILE_RESERVE_OPFILTER 标志对这些 oplock 类型毫无用。

NTFS 是实现 FILE_RESERVE_OPFILTER的唯一Microsoft文件系统。

有关 oplock 的详细信息,请参阅 机会锁

请注意,许多常量定义以及 InitializeObjectAttributes 宏都需要 WDK 头文件 NtDef.h。 还可以使用 LoadLibraryGetProcAddress 函数动态链接到 NtDll.dll。

要求

要求 价值
目标平台 窗户
标头 winternl.h
ntdll.lib
DLL ntdll.dll