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 标志决定了文件对象的以下特定访问权限。
NtCreateFile 的调用方可以为不表示目录文件的任何文件对象指定一个或组合,可能对上述 DesiredAccess 标志列表使用按位或附加兼容标志。
FILE_GENERIC_EXECUTE 值与设备和中间驱动程序无关。
STANDARD_RIGHTS_XXX 是预定义的系统值,用于对系统对象强制执行安全性。
若要打开或创建目录文件,如 CreateOptions 参数所示,NtCreateFile 的调用方可以指定以下的一个或多个兼容标志,可能对上述 DesiredAccess 标志列表使用按位或组合。
价值 | 意义 |
---|---|
|
可以列出目录中的文件。 |
|
可以遍历目录:也就是说,它可以是文件路径名的一部分。 |
[in] ObjectAttributes
指向已使用 InitializeObjectAttributes初始化的结构的指针。 文件对象的此结构的成员包括以下内容。
价值 | 意义 |
---|---|
|
指定提供的 ObjectAttributes 数据的字节数。 此值必须至少为 sizeof(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返回时,信息 成员包含以下值之一:
- 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
调用方想要在文件中使用的共享访问类型,为零,或用作以下值的一个或多个组合。
价值 | 意义 |
---|---|
|
可以通过其他线程调用 NtCreateFile打开该文件进行读取访问。 |
|
可以通过其他线程调用 NtCreateFile来打开该文件进行写入访问。 |
|
可以通过其他线程调用 NtCreateFile打开该文件以删除访问权限。 |
有关详细信息,请参阅 Windows SDK。
[in] CreateDisposition
指定要执行的操作,具体取决于文件是否已存在,作为以下值之一。
[in] CreateOptions
创建或打开文件时要应用的选项,作为以下标志的兼容组合。
[in] EaBuffer
指向用于传递扩展属性的 EA 缓冲区的指针。
[in] EaLength
EA 缓冲区的长度。
返回值
NtCreateFile 返回 STATUS_SUCCESS 或适当的错误状态。 如果返回错误状态,调用方可以通过检查 IoStatusBlock来查找有关失败原因的详细信息。 为了简化此检查,应用程序可以使用 NT_SUCCESS、NT_ERROR和 NT_WARNING 宏。
言论
NtCreateFile提供的句柄可由后续调用用来操作文件或文件对象的状态或属性中的数据。
可通过两种替代方法指定要创建或打开的文件的名称,NtCreateFile:
- 作为完全限定的路径名,在输入 ObjectAttributes 的 ObjectName 成员中提供
- 作为路径名称,相对于由输入 ObjectAttributes 的 RootDirectory 成员中的句柄表示的目录文件
某些 DesiredAccess 标志和标志的组合具有以下效果:
- 若要使调用方通过等待返回的 FileHandle来同步 I/O 完成,必须设置 SYNCHRONIZE 标志。
- 将零传递给 DesiredFlags 无效。
- 如果仅设置了 FILE_APPEND_DATA 和 SYNCHRONIZE 标志,则调用方只能写入文件末尾,并且忽略对文件写入的任何偏移信息。 但是,根据这种类型的写入操作,文件会自动扩展。
- 设置文件的 FILE_WRITE_DATA 标志还允许在文件末尾之外进行写入。 该文件也会自动扩展为这种类型的写入。
- 如果仅设置了 FILE_EXECUTE 和 SYNCHRONIZE 标志,则调用方无法使用返回的 FileHandle直接读取或写入文件中的任何数据,也就是说,文件上的所有操作都通过系统寻呼器来响应指令和数据访问。
ShareAccess 参数确定单独的线程是否可以同时访问同一文件。 如果两个文件打开者都有权以指定方式访问文件,则可以成功打开和共享该文件。 如果 NtCreateFile 的原始调用方未指定 FILE_SHARE_READ、FILE_SHARE_WRITE或 FILE_SHARE_DELETE,则无法对文件执行其他打开操作;也就是说,原始调用方对文件具有独占访问权限。
若要成功打开共享文件,所请求的 DesiredAccess 参数必须与 DesiredAccess 和 ShareAccess 规范兼容,这些规范尚未随 NtClose一起发布。 也就是说,为给定文件的 NtCreateFile 指定的 DesiredAccess 参数不得与不允许文件的其他打开者访问冲突。
CreateDisposition 值 FILE_SUPERSEDE 要求调用方具有对现有文件对象的 DELETE 访问权限。 如果是这样,则成功调用 NtCreateFile,并在现有文件上 FILE_SUPERSEDE 有效删除该文件,然后重新创建该文件。 这意味着,如果文件已被另一个线程打开,则它通过指定具有 FILE_SHARE_DELETE 标志集的 ShareAccess 参数来打开该文件。
请注意,这种类型的处置与覆盖文件的 POSIX 样式一致。
CreateDisposition 值 FILE_OVERWRITE_IF 和 FILE_SUPERSEDE 相似。 如果使用现有文件调用 ZwCreateFile
覆盖文件在语义上等效于取代操作,但以下情况除外:
- 调用方必须具有对文件的写入访问权限,而不是删除访问权限。 这意味着,如果文件已被另一个线程打开,则会打开该文件,并在输入 ShareAccess 参数中设置 FILE_SHARE_WRITE 标志。
- 指定的文件属性在逻辑上为 ORed,该文件中已存在这些属性。 这意味着,如果文件已被另一个线程打开,则 NtCreateFile 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。 请注意,此覆盖文件的样式与 MS-DOS、Windows 3.1 和 OS/2 操作系统一致。
CreateOptionsFILE_DIRECTORY_FILE 值指定要创建或打开的文件是目录文件。 创建目录文件时,文件系统会在磁盘上创建适当的结构,以表示该特定文件系统磁盘结构中的空目录。 如果指定了此选项并且要打开的给定文件不是目录文件,或者调用方指定了不一致的 createOptions 或 CreateDisposition 值,则对 NtCreateFile 的调用将失败。
CreateOptionsFILE_NO_INTERMEDIATE_BUFFERING 标志阻止文件系统代表调用方执行任何中间缓冲。 指定此值会将调用方参数的某些限制置于其他 NtXXXFile 例程,包括:
- 传递给 NtReadFile 或 NtWriteFile 函数的任何可选 ByteOffset 必须是扇区大小的整型。
- 传递给 NtReadFile 或 NtWriteFile的 长度 必须是扇区大小的一个整数。 请注意,指定对缓冲区的读取操作(其长度正好是扇区大小)可能会导致在传输过程中到达文件的末尾时,将较少的有效字节传输到该缓冲区。
- 必须根据基础设备的对齐要求调整缓冲区。 可以通过调用 NtCreateFile 获取此信息,以获取表示物理设备的文件对象的句柄,然后使用该句柄调用 NtQueryInformationFile。 有关系统 FILE_XXX_ALIGNMENT 值的列表,请参阅 Windows SDK 文档。
- 调用 NtSetInformationFile,FileInformationClass 参数设置为 FilePositionInformation 必须指定扇区大小的整型偏移量。
如果 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 请求失败后关闭其句柄。
CreateOptions 参数的 FILE_RESERVE_OPFILTER 标志允许应用程序请求级别 1、Batch 或 Filter oplock,以防止其他应用程序出现共享冲突。 但是,在实际情况下,FILE_RESERVE_OPFILTER 仅适用于筛选器 oplock。 若要使用它,必须完成以下步骤:
-
CreateOptionsFILE_RESERVE_OPFILTER、DesiredAccess 完全 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。
- 如果创建请求成功,请请求 oplock。
- 打开文件的另一个句柄以执行 I/O。
(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNCHRONIZE | READ_CONTROL)
,并且仍然不会中断筛选器操作锁。 但是,任何大于 NTFS 是实现 FILE_RESERVE_OPFILTER的唯一Microsoft文件系统。
有关 oplock 的详细信息,请参阅 机会锁。
请注意,许多常量定义以及 InitializeObjectAttributes 宏都需要 WDK 头文件 NtDef.h。 还可以使用 LoadLibrary 和 GetProcAddress 函数动态链接到 NtDll.dll。
要求
要求 | 价值 |
---|---|
目标平台 | 窗户 |
标头 | winternl.h |
库 | ntdll.lib |
DLL | ntdll.dll |