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 标志集确定文件对象的以下特定访问权限。
创建或打开目录时,请勿指定FILE_READ_DATA、FILE_WRITE_DATA、FILE_APPEND_DATA或FILE_EXECUTE。
NtCreateFile 的调用方可以为不表示目录文件的任何文件对象指定以下一个或组合,可能使用按位 OR 和前面 DesiredAccess 标志列表中的其他兼容标志。
FILE_GENERIC_EXECUTE值与设备和中间驱动程序无关。
STANDARD_RIGHTS_XXX 是预定义的系统值,用于在系统对象上强制实施安全性。
若要打开或创建目录文件,如 CreateOptions 参数所示, NtCreateFile 的调用方可以指定以下一个或一个组合,可能使用按位 OR 和上述 DesiredAccess 标志列表中的一个或多个兼容标志。
值 | 含义 |
---|---|
|
目录中的文件可以列出。 |
|
可以遍历目录:也就是说,它可以是文件路径名的一部分。 |
[in] ObjectAttributes
指向已使用 InitializeObjectAttributes 初始化的 结构的指针。 文件对象的此结构的成员包括以下内容。
值 | 含义 |
---|---|
|
指定提供的 ObjectAttributes 数据的字节数。 此值的大小必须至少为 (OBJECT_ATTRIBUTES) 。 |
|
(可选)指定由先前对 NtCreateFile 的调用获取的目录的句柄。 如果此值为 NULL, 则 ObjectName 成员必须是包含目标文件的完整路径的完全限定文件规范。 如果此值为非 NULL,则 ObjectName 成员指定相对于此目录的文件名。 |
|
指向命名要创建或打开的文件的缓冲 Unicode 字符串。 此值必须是完全限定的文件规范或设备对象的名称,除非它是相对于 RootDirectory 指定的目录的文件的名称。 例如,\Device\Floppy1\myfile.dat 或 \??\B:\myfile.dat 可以是完全限定的文件规范,前提是已加载软盘驱动程序和覆盖文件系统。 有关详细信息,请参阅 文件名、路径和命名空间。 |
|
控制文件对象属性的一组标志。 此值可以为零或 OBJ_CASE_INSENSITIVE,这表示名称查找代码应忽略 ObjectName 成员的大小写,而不是执行完全匹配的搜索。 OBJ_INHERIT的值与设备和中间驱动程序无关。 |
|
(可选)指定要应用于文件的安全描述符。 此类安全描述符指定的 ACL 仅在创建文件时应用于该文件。 如果创建文件时的值为 NULL ,则放置在该文件上的 ACL 依赖于文件系统;大多数文件系统从父目录文件传播此类 ACL 的某些部分,并结合调用方的默认 ACL。 设备和中间驱动程序可以将此成员设置为 NULL。 |
|
指定服务器应授予对客户端安全上下文的访问权限。 仅当与受保护服务器建立连接时,此值才为非 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
调用方希望在文件中使用的共享访问类型,为零,或者作为以下值的一个或组合。
值 | 含义 |
---|---|
|
可以通过其他线程对 NtCreateFile 的调用打开该文件进行读取访问。 |
|
可以通过其他线程对 NtCreateFile 的调用打开该文件进行写入访问。 |
|
通过其他线程对 NtCreateFile 的调用,可以打开该文件进行删除访问。 |
有关详细信息,请参阅 Windows SDK。
[in] CreateDisposition
指定操作,具体取决于文件是否已存在,作为以下值之一。
[in] CreateOptions
创建或打开文件时要应用的选项,作为以下标志的兼容组合。
值 | 含义 |
---|---|
|
正在创建或打开的文件是目录文件。 使用此标志时, CreateDisposition 参数必须设置为 FILE_CREATE、 FILE_OPEN 或 FILE_OPEN_IF。 使用此标志,其他兼容的 CreateOptions 标志仅包括以下内容: FILE_SYNCHRONOUS_IO_ALERT、 FILE_SYNCHRONOUS_IO _NONALERT、 FILE_WRITE_THROUGH、 FILE_OPEN_FOR_BACKUP_INTENT和 FILE_OPEN_BY_FILE_ID。 |
|
打开的文件不能是目录文件,否则此调用将失败。 正在打开的文件对象可以表示数据文件、逻辑、虚拟或物理设备或卷。 |
|
将数据写入文件的应用程序必须实际将数据传输到文件,然后才能将请求的任何写入操作视为完成。 如果设置了 CreateOptions 标志 FILE_NO_INTERMEDIATE _BUFFERING ,则会自动设置此标志。 |
|
对文件的所有访问都是连续的。 |
|
对文件的访问可以是随机的,因此 FSD 或系统不应对文件执行顺序的预读操作。 |
|
不能在驱动程序的内部缓冲区中缓存或缓冲该文件。 此标志与 DesiredAccessFILE_APPEND_DATA 标志不兼容。 |
|
对文件执行的所有操作都是同步执行的。 代表调用方的任何等待都可能会提前终止警报。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccessSYNCHRONIZE 标志。 |
|
对文件执行的所有操作都是同步执行的。 在系统中等待同步 I/O 队列和完成不受警报约束。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccessSYNCHRONIZE 标志。 |
|
为此文件创建树连接,以便通过网络打开它。 设备和中间驱动程序不使用此标志。 |
|
如果打开的现有文件的扩展属性指示调用方必须了解 EA 才能正确解释文件,则失败此请求,因为调用方不了解如何处理 EA。 此标志与设备和中间驱动程序无关。 |
|
打开具有重分析点的文件,并绕过该文件的正常重分析点处理。 有关详细信息,请参见“备注”部分。 |
|
将文件的最后一个句柄传递给 NtClose 时,请删除该文件。 如果设置了此标志,则必须在 DesiredAccess 参数中设置 DELETE 标志。 |
|
由 ObjectAttributes 参数指定的文件名包括文件的 8 字节文件引用号。 此编号由 特定文件系统分配,并特定于特定文件系统。 如果文件是重分析点,则文件名还将包含设备的名称。 请注意,FAT 文件系统不支持此标志。 设备和中间驱动程序不使用此标志。 |
|
正在为备份意向打开文件。 因此,系统应检查某些访问权限,并在根据文件的安全描述符检查 DesiredAccess 参数之前授予调用方对文件的相应访问权限。 设备和中间驱动程序不使用此标志。 |
|
此标志允许应用程序请求筛选器机会锁 (oplock) ,以防止其他应用程序发生共享冲突。 如果已有打开的句柄,则创建请求将失败并 STATUS_OPLOCK_NOT_GRANTED。 有关详细信息,请参见“备注”部分。 |
|
正在打开文件,并且正在以单个原子操作的形式请求对文件) oplock (机会锁。 文件系统在执行创建操作之前会检查 oplock,如果结果将中断现有的 oplock,则会使创建失败并返回 STATUS_CANNOT_BREAK_OPLOCK 代码。 有关详细信息,请参阅“备注”部分。Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支持此标志。
以下文件系统支持此标志:NTFS、FAT 和 exFAT。 |
|
如果目标文件已锁定,则立即使用备用成功代码 STATUS_OPLOCK_BREAK_IN_PROGRESS 完成此操作,而不是阻止调用方线程。 如果文件 已锁定,则另一个调用方已有权访问该文件。 设备和中间驱动程序不使用此标志。 |
[in] EaBuffer
指向用于传递扩展属性的 EA 缓冲区的指针。
[in] EaLength
EA 缓冲区的长度。
返回值
NtCreateFile 返回 STATUS_SUCCESS 或适当的错误状态。 如果返回错误状态,则调用方可以通过检查 IoStatusBlock 找到有关失败原因的详细信息。 为了简化此检查,应用程序可以使用NT_SUCCESS、NT_ERROR和NT_WARNING宏。
注解
由 NtCreateFile 提供的句柄可由后续调用使用,以操作文件中的数据或文件对象的状态或属性。
可通过两种替代方法指定要使用 NtCreateFile 创建或打开的文件的名称:
- 作为完全限定的路径名,在输入 ObjectAttributes 的 ObjectName 成员中提供
- 作为相对于输入 ObjectAttributes 的 RootDirectory 成员中的句柄表示的目录文件的路径名
- 对于通过等待返回 的 FileHandle 来同步 I/O 完成的调用方,必须设置 SYNCHRONIZE 标志。
- 将零传递到 DesiredFlags 无效。
- 如果仅设置了 FILE_APPEND_DATA 和 SYNCHRONIZE 标志,则调用方只能写入文件末尾,并且将忽略有关写入文件的任何偏移量信息。 但是,对于这种类型的写入操作,文件会自动扩展。
- 为文件设置 FILE_WRITE_DATA 标志还允许在文件末尾之外进行写入。 文件也会自动扩展为此类写入。
- 如果只设置了 FILE_EXECUTE 和 SYNCHRONIZE 标志,则调用方无法使用返回的 FileHandle 直接读取或写入文件中的任何数据,也就是说,对文件的所有操作都通过系统寻呼程序进行,以响应指令和数据访问。
若要成功打开共享文件,文件请求的 DesiredAccess 参数必须与之前尚未使用 NtClose 发布的所有打开的 DesiredAccess 和 ShareAccess 规范兼容。 也就是说,指定给给定文件的 NtCreateFile 的 DesiredAccess 参数不得与该文件的其他打开程序禁止的访问发生冲突。
CreateDisposition 值FILE_SUPERSEDE要求调用方对现有文件对象具有 DELETE 访问权限。 如果是这样,如果成功调用 NtCreateFile 并 FILE_SUPERSEDE 现有文件,则会有效地删除该文件,然后重新创建该文件。 这意味着,如果文件已被另一个线程打开,则它通过指定一个 ShareAccess 参数来打开 文件, 并设置了 FILE_SHARE_DELETE 标志。 请注意,这种类型的处置与覆盖文件的 POSIX 样式一致。 CreateDisposition值FILE_OVERWRITE_IF和FILE_SUPERSEDE相似。 如果使用现有文件以及其中任一 CreateDisposition 值调用 ZwCreateFile,则会替换该文件。
覆盖文件在语义上等效于取代操作,但以下情况除外:
- 调用方必须对文件具有写入访问权限,而不是删除访问权限。 这意味着,如果文件已由另一个线程打开,它将打开文件,并在输入 ShareAccess 参数中设置FILE_SHARE_WRITE标志。
- 指定的文件属性在逻辑上与文件上已有的属性一起为 ORed。 这意味着,如果文件已由另一个线程打开, 则 NtCreateFile 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。 请注意,这种覆盖文件的样式与 MS-DOS、Windows 3.1 和 OS/2 操作系统一致。
CreateOptionsFILE_NO_INTERMEDIATE_BUFFERING 标志阻止文件系统代表调用方执行任何中间缓冲。 指定此值对其他 NtXXX文件 例程的调用方参数进行某些限制,包括:
- 传递给 NtReadFile 或 NtWriteFile 函数的任何可选 ByteOffset 都必须是扇区大小的整数。
- 传递给 NtReadFile 或 NtWriteFile 的 Length 必须是扇区大小的整数。 请注意,如果在传输过程中到达文件的末尾,则指定对长度正好为扇区大小的缓冲区的读取操作可能会导致传输到该缓冲区的重要字节数减少。
- 必须根据基础设备的对齐要求调整缓冲区。 可以通过调用 NtCreateFile 获取表示物理设备的文件对象的句柄,然后使用该句柄调用 NtQueryInformationFile 来获取此信息。 有关系统FILE_XXX_ALIGNMENT值的列表,请参阅Windows SDK文档。
- 对 FileInformationClass 参数设置为 FilePositionInformation 的 NtSetInformationFile 的调用必须指定作为扇区大小的整数的偏移量。
如果 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 请求失败后关闭其句柄。
CreateOptions 参数的FILE_RESERVE_OPFILTER标志允许应用程序请求 Level 1、Batch 或 Filter oplock,以防止其他应用程序发生共享冲突。 但是,实际上, FILE_RESERVE_OPFILTER 仅适用于筛选器 oplock。 若要使用它,必须完成以下步骤:
- 发出创建请求,其中 CreateOptions为 FILE_RESERVE_OPFILTER,DesiredAccess 为 exactly 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。
- 如果创建请求成功,请请求 oplock。
- 打开文件的另一个句柄以执行 I/O。
(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 宏是必需的。 还可以使用 LoadLibrary 和 GetProcAddress 函数动态链接到 NtDll.dll。
要求
要求 | 值 |
---|---|
目标平台 | Windows |
标头 | winternl.h |
Library | ntdll.lib |
DLL | ntdll.dll |
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈