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
可以写入与该文件关联的扩展属性 () 。 此标志与设备和中间驱动程序无关。
FILE_APPEND_DATA
可将数据追加到文件。
WRITE_DAC
可以写入与该文件关联的 DACL) (自由访问控制列表。
WRITE_OWNER
可以写入与文件关联的所有权信息。
SYNCHRONIZE
返回的 FileHandle 可以等待与 I/O 操作完成同步。 如果未为同步 I/O 打开 FileHandle ,则忽略此值。
FILE_EXECUTE
可以使用系统分页 I/O 将数据从文件读入内存中。 此标志与设备和中间驱动程序无关。
 

创建或打开目录时,请勿指定FILE_READ_DATAFILE_WRITE_DATA、FILE_APPEND_DATAFILE_EXECUTE

NtCreateFile 的调用方可以为不表示目录文件的任何文件对象指定以下一个或组合,可能使用按位 OR 和前面 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 的调用方可以指定以下一个或一个组合,可能使用按位 OR 和上述 DesiredAccess 标志列表中的一个或多个兼容标志。

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

[in] ObjectAttributes

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

含义
ULONG 长度
指定提供的 ObjectAttributes 数据的字节数。 此值的大小必须至少为 (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 返回时, Information 成员包含以下值之一:

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

[in, optional] AllocationSize

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

[in] FileAttributes

文件属性。 仅当创建、取代文件或在某些情况下覆盖文件时,才会应用显式指定的属性。 默认情况下,此值是 FILE_ATTRIBUTE_NORMAL,可由 Wdm.h 和 NtDdk.h 中定义的一个或多个 FILE_ATTRIBUTE_xxxx 标志的 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
此标志允许应用程序请求筛选器机会锁 (oplock) ,以防止其他应用程序发生共享冲突。 如果已有打开的句柄,则创建请求将失败并 STATUS_OPLOCK_NOT_GRANTED。 有关详细信息,请参见“备注”部分。
FILE_OPEN_REQUIRING_OPLOCK
正在打开文件,并且正在以单个原子操作的形式请求对文件) oplock (机会锁。 文件系统在执行创建操作之前会检查 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 完成此操作,而不是阻止调用方线程。 如果文件 已锁定,则另一个调用方已有权访问该文件。 设备和中间驱动程序不使用此标志。

[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 参数必须与之前尚未使用 NtClose 发布的所有打开的 DesiredAccessShareAccess 规范兼容。 也就是说,指定给给定文件的 NtCreateFileDesiredAccess 参数不得与该文件的其他打开程序禁止的访问发生冲突。

CreateDispositionFILE_SUPERSEDE要求调用方对现有文件对象具有 DELETE 访问权限。 如果是这样,如果成功调用 NtCreateFileFILE_SUPERSEDE 现有文件,则会有效地删除该文件,然后重新创建该文件。 这意味着,如果文件已被另一个线程打开,则它通过指定一个 ShareAccess 参数来打开 文件, 并设置了 FILE_SHARE_DELETE 标志。 请注意,这种类型的处置与覆盖文件的 POSIX 样式一致。 CreateDisposition值FILE_OVERWRITE_IFFILE_SUPERSEDE相似。 如果使用现有文件以及其中任一 CreateDisposition 值调用 ZwCreateFile,则会替换该文件。

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

  • 调用方必须对文件具有写入访问权限,而不是删除访问权限。 这意味着,如果文件已由另一个线程打开,它将打开文件,并在输入 ShareAccess 参数中设置FILE_SHARE_WRITE标志。
  • 指定的文件属性在逻辑上与文件上已有的属性一起为 ORed。 这意味着,如果文件已由另一个线程打开, 则 NtCreateFile 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。 请注意,这种覆盖文件的样式与 MS-DOS、Windows 3.1 和 OS/2 操作系统一致。
CreateOptionsFILE_DIRECTORY_FILE 值指定要创建或打开的文件是目录文件。 创建目录文件时,文件系统会在磁盘上创建适当的结构,以表示该特定文件系统的磁盘上结构的空目录。 如果指定了此选项,并且要打开的给定文件不是目录文件,或者调用方指定了不一致的 CreateOptionsCreateDisposition 值,则对 NtCreateFile 的调用将失败。

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

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

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

CreateOptions 参数的FILE_OPEN_REQUIRING_OPLOCK标志消除了打开文件与请求 oplock 之间的时间,因为 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 请求失败,则使用此标志的应用程序必须在检测到 oplock 请求失败后关闭其句柄。

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

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

  1. 发出创建请求,其中 CreateOptions为 FILE_RESERVE_OPFILTER,DesiredAccessexactly FILE_READ_ATTRIBUTES,ShareAccess 为 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) 可能的失败如下:
    • 如果已打开句柄,则创建请求会失败 并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) 且仍不中断筛选器 oplock。 但是,任何大于(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE)的 DesiredAccess 都会中断级别 1 或 Batch oplock,并使FILE_RESERVE_OPFILTER标志对这些 oplock 类型无用。

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

有关 oplock 的详细信息,请参阅 Oplock 语义

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

要求

要求
目标平台 Windows
标头 winternl.h
Library ntdll.lib
DLL ntdll.dll