NtCreateNamedPipeFile 函数
创建并打开特定命名管道的第一个实例或现有命名管道的另一个实例的服务器端句柄。 函数返回可用于访问管道的句柄。
语法
NTSTATUS NtCreateNamedPipeFile(
[out] PHANDLE FileHandle,
[in] ULONG DesiredAccess,
[in] POBJECT_ATTRIBUTES ObjectAttributes,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[in] ULONG ShareAccess,
[in] ULONG CreateDisposition,
[in] ULONG CreateOptions,
[in] ULONG NamedPipeType,
[in] ULONG ReadMode,
[in] ULONG CompletionMode,
[in] ULONG MaximumInstances,
[in] ULONG InboundQuota,
[in] ULONG OutboundQuota,
[in, optional] PLARGE_INTEGER DefaultTimeout
);
参数
FileHandle [out]
指向在调用成功时接收文件句柄的变量的指针。
DesiredAccess [in]
标志的位掩码,指定调用方所需的文件或目录的访问类型。 这组系统定义的 DesiredAccess 标志确定文件对象的以下特定访问权限。
标志 | 说明 |
---|---|
DELETE | 可以删除该文件。 |
FILE_READ_DATA | 可从文件中读取数据。 |
FILE_READ_ATTRIBUTES | 可以读取下面所述的 FileAttributes 标志。 |
FILE_READ_EA | 可以读取与该文件关联的扩展属性 (CA) 。 |
READ_CONTROL | 可以读取与该文件关联的访问控制列表 (ACL) 和所有权信息。 |
FILE_WRITE_DATA | 可将数据写入文件。 |
FILE_WRITE_ATTRIBUTES | 可以写入 FileAttributes 标志。 |
FILE_WRITE_EA | 可以写入与文件关联的 CA。 |
FILE_APPEND_DATA | 可将数据追加到文件。 |
WRITE_DAC | 可以编写与该文件关联的自由访问控制列表 (DACL) 。 |
WRITE_OWNER | 可以写入与文件关联的所有权信息。 |
SYNCHRONIZE | 调用方可以通过等待返回的 FileHandle 设置为 Signaled 状态来同步 I/O 操作的完成。 如果设置了 CreateOptionsFILE_SYNCHRONOUS_IO_ALERT 或 FILE_SYNCHRONOUS_IO_NONALERT 标志,则必须设置此标志。 |
FILE_EXECUTE | 可以使用系统分页 I/O 将数据从文件读入内存中。 |
或者,对于不表示目录的任何文件对象,可以指定以下一个或多个泛 型ACCESS_MASK 标志。 STANDARD_RIGHTS_XXX标志是预定义的系统值,用于在系统对象上强制实施安全性。 还可以将这些泛型标志与上表中的其他标志组合在一起。
对文件值的所需访问权限 | 映射到 DesiredAccess 标志 |
---|---|
GENERIC_READ | STANDARD_RIGHTS_READ、FILE_READ_DATA、FILE_READ_ATTRIBUTES、FILE_READ_EA、SYNCHRONIZE。 |
GENERIC_WRITE | STANDARD_RIGHTS_WRITE、FILE_WRITE_DATA、FILE_WRITE_ATTRIBUTES、FILE_WRITE_EA、FILE_APPEND_DATA、SYNCHRONIZE。 |
GENERIC_EXECUTE | STANDARD_RIGHTS_EXECUTE、SYNCHRONIZE、FILE_READ_ATTRIBUTES、FILE_EXECUTE。 |
对于 (FILE_DIRECTORY_FILE
CreateOptions 标志设置为) 的目录,可以指定以下一个或多个 ACCESS_MASK 标志,这些标志也可以与前面所述的任何兼容标志结合使用。
对目录值的所需访问权限 | 说明 |
---|---|
FILE_LIST_DIRECTORY | 目录中的文件可以列出。 |
FILE_TRAVERSE | 可以遍历目录;也就是说,它可以是文件路径名的一部分。 |
FILE_READ_DATA
、FILE_WRITE_DATA
、 FILE_EXECUTE
和 FILE_APPEND_DATA
DesiredAccess 标志与创建或打开目录文件不兼容。
ObjectAttributes [in]
指向 OBJECT_ATTRIBUTES
已由 InitializeObjectAttributes 例程初始化的 结构的指针。 如果调用方在系统进程上下文中运行,则此参数可以是 NULL
。 否则,调用方必须在对 InitializeObjectAttributes 的调用中设置 OBJ_KERNEL_HANDLE
属性。
文件对象的此结构的成员包括:
成员 | Value |
---|---|
ULONG 长度 | 提供的 ObjectAttributes 数据的字节数。 此值必须至少 sizeof(OBJECT_ATTRIBUTES) 为 。 |
PUNICODE_STRING ObjectName | 指向缓冲 Unicode 字符串的指针,该字符串包含要创建或打开的文件的名称。 此值必须是完全限定的文件规范,除非它是相对于 RootDirectory 指定的目录的文件的名称。 例如,“\Device\Floppy1\myfile.dat”或“??\B:\myfile.dat“可以是完全限定的文件规范,前提是已加载软盘驱动器驱动程序和过度文件系统。 (注意:“??”将“\DosDevices”替换为 Win32 对象命名空间的名称。“\DosDevices”仍然有效,但对象管理器可以更快地转换“??”) |
HANDLE RootDirectory | 由先前调用 NtCreateNamedPipeFile 获取的目录的可选句柄。 如果此值为 NULL, 则 ObjectName 成员必须是包含目标文件的完整路径的完全限定文件规范。 如果此值为非 NULL,则 ObjectName 成员指定相对于此目录的文件名。 |
PSECURITY_DESCRIPTOR SecurityDescriptor | 要应用于文件的可选安全描述符。 此类安全描述符指定的 ACL 仅在创建文件时应用于该文件。 如果创建文件时的值为 NULL,则放置在该文件上的 ACL 依赖于文件系统;大多数文件系统从父目录文件传播此类 ACL 的某些部分,并结合调用方的默认 ACL。 |
ULONG 属性 | 一组控制文件对象属性的标志。 如果调用方在系统进程上下文中运行,则此参数可以为零。 否则,调用方必须设置 OBJ_KERNEL_HANDLE 标志。 调用方还可以选择性地设置 OBJ_CASE_INSENSITIVE 标志,该标志指示名称查找代码应忽略 ObjectName 的大小写,而不是执行完全匹配的搜索。 |
IoStatusBlock [out]
指向 类型的 IO_STATUS_BLOCK
变量的指针,该变量接收最终完成状态和有关所请求操作的信息。 从 NtCreateNamedPipeFile 返回时,变量的 Information 成员包含以下值之一:
- FILE_CREATED
- FILE_OPENED
- FILE_OVERWRITTEN
- FILE_SUPERSEDED
- FILE_EXISTS
- FILE_DOES_NOT_EXIST
ShareAccess [in]
指定调用方希望的对文件的共享访问类型,指定为零、1 或以下标志的组合。 若要请求独占访问权限,请将此参数设置为零。 为帮助你避免共享冲突错误,请指定以下所有共享访问标志。
ShareAccess 标志 | 说明 |
---|---|
FILE_SHARE_READ | 可以通过其他线程的文件创建调用打开该文件进行读取访问。 |
FILE_SHARE_WRITE | 可以通过其他线程的文件创建调用打开该文件进行写入访问。 |
FILE_SHARE_DELETE | 可以通过其他线程的文件创建调用打开该文件以删除访问权限。 |
设备驱动程序和中间驱动程序通常将 ShareAccess 设置为零,这使调用方能够独占访问打开的文件。
CreateDisposition [in]
确定文件已存在时应如何处理文件的值。 CreateDisposition 可以是下列项之一:
值 | 说明 |
---|---|
FILE_SUPERSEDE | 如果文件已存在,请将其替换为给定的文件。 如果不存在,请创建给定的文件。 |
FILE_CREATE | 如果文件已存在,则使请求失败,并且不会创建或打开给定的文件。 如果不存在,请创建给定的文件。 |
FILE_OPEN | 如果文件已存在,请打开它,而不是创建新文件。 如果不存在,请使请求失败,并且不创建新文件。 |
FILE_OPEN_IF | 如果文件已存在,请将其打开。 如果不存在,请创建给定的文件。 |
FILE_OVERWRITE | 如果文件已存在,请将其打开并覆盖。 如果不存在,则使请求失败。 |
FILE_OVERWRITE_IF | 如果文件已存在,请将其打开并覆盖。 如果不存在,请创建给定的文件。 |
CreateOptions [in]
指定在创建或打开文件时要应用的选项,作为以下标志的兼容组合。
CreateOptions 标志 | 说明 |
---|---|
FILE_DIRECTORY_FILE (0x00000001) | 正在创建或打开的文件是目录文件。 使用此标志时,Disposition 参数必须设置为 、 FILE_OPEN 或 FILE_OPEN_IF 中的FILE_CREATE 一个。 与此标志兼容的 CreateOptions 标志如下所示:FILE_SYNCHRONOUS_IO_ALERT 、、FILE_SYNCHRONOUS_IO_NONALERT FILE_WRITE_THROUGH 、 FILE_OPEN_FOR_BACKUP_INTENT 和 FILE_OPEN_BY_FILE_ID 。 |
FILE_WRITE_THROUGH (0x00000002) | 将数据写入文件的系统服务、文件系统和驱动程序必须实际将数据传输到文件,然后才能将请求的任何写入操作视为完成。 |
FILE_SEQUENTIAL_ONLY (0x00000004) | 对文件的所有访问都是按顺序进行的。 |
FILE_NO_INTERMEDIATE_BUFFERING (0x00000008) | 不能在驱动程序的内部缓冲区中缓存或缓冲该文件。 此标志与 DesiredAccessFILE_APPEND_DATA 标志不兼容。 |
FILE_SYNCHRONOUS_IO_ALERT (0x00000010) | 对文件执行的所有操作都是同步执行的。 代表调用方的任何等待都可能会提前终止警报。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccessSYNCHRONIZE 标志,以便 I/O 管理器将文件对象用作同步对象。 |
FILE_SYNCHRONOUS_IO_NONALERT (0x00000020) | 对文件执行的所有操作都是同步执行的。 在系统中等待同步 I/O 队列和完成不受警报约束。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccessSYNCHRONIZE 标志,以便 I/O 管理器将文件对象用作同步对象。 |
FILE_NON_DIRECTORY_FILE (0x00000040) | 打开的文件不能是目录文件,否则此调用将失败。 正在打开的文件对象可以表示数据文件;逻辑、虚拟或物理设备;或卷。 |
FILE_CREATE_TREE_CONNECTION (0x00000080) | 为此文件创建树连接,以便通过网络打开它。 |
FILE_COMPLETE_IF_OPLOCKED (0x00000100) | 如果目标文件已锁定,请使用备用成功代码立即完成此操作,而不是阻止调用方线程。 如果文件已锁定,则另一个调用方已通过网络访问该文件。 |
FILE_NO_EA_KNOWLEDGE (0x00000200) | 如果打开的现有文件的扩展属性指示调用方必须了解扩展属性才能正确解释文件,则失败此请求,因为调用方不了解如何处理扩展属性。 |
FILE_OPEN_REMOTE_INSTANCE (0x00000400) | 保留供系统使用;请勿使用。 |
FILE_RANDOM_ACCESS (0x00000800) | 对文件的访问可以是随机的,因此文件系统或操作系统不应对文件执行顺序预读操作。 |
FILE_DELETE_ON_CLOSE (0x00001000) | 当文件的最后一个句柄传递给 FltClose 时,请删除该文件。 |
FILE_OPEN_BY_FILE_ID (0x00002000) | 文件正在按 ID 打开。 文件名包含设备名称和用于打开文件的 64 位 ID。 |
FILE_OPEN_FOR_BACKUP_INTENT (0x000004000) | 正在为备份意向打开文件;因此,系统应检查某些访问权限,并在根据文件的安全描述符检查输入 DesiredAccess 之前授予调用方对文件的相应访问权限。 |
FILE_NO_COMPRESSION (0x00008000) | 禁止从父目录继承 。FILE_ATTRIBUTE_COMPRESSED 这允许在标记为已压缩的目录中创建非压缩文件。 |
FILE_OPEN_REQUIRING_OPLOCK (0x00010000) | 正在打开文件,并且正在以单个原子操作的形式请求对文件 (oplock) 的机会锁。 文件系统在执行创建操作之前检查 oplock,如果创建操作会中断现有的 oplock,则创建操作将失败并返回返回代码 STATUS_CANNOT_BREAK_OPLOCK 。 此标志在 Windows 7、Windows Server 2008 R2 和更高版本的 Windows 操作系统中可用。 |
FILE_DISALLOW_EXCLUSIVE (0x00020000) | 打开现有文件时,如果未FILE_SHARE_READ 指定 ,并且文件系统访问检查不会授予调用方对该文件的写入访问权限,则打开时会失败。STATUS_ACCESS_DENIED 这是 Windows 7 之前的默认行为。 |
FILE_SESSION_AWARE (0x00040000) | 正在使用会话感知打开文件或设备。 如果未指定此标志,则会话 0 中运行的进程无法打开每个会话 (设备,例如使用 RemoteFX USB 重定向) 的设备。 此标志对不在会话 0 中的调用方无效。 此标志仅在服务器版本的 Windows 上受支持。 在Windows Server 2012之前,不支持此标志。 |
FILE_RESERVE_OPFILTER (0x00100000) | 此标志允许应用程序请求筛选器机会锁 (oplock) ,以防止其他应用程序发生共享冲突。 如果已有打开的句柄,则创建请求将失败并出现 STATUS_OPLOCK_NOT_GRANTED 。 |
FILE_OPEN_REPARSE_POINT (0x00200000) | 打开具有重分析点的文件,并绕过该文件的正常重分析点处理。 有关更多信息,请参见下面的“备注”部分。 |
FILE_OPEN_NO_RECALL (0x00400000) | 指示执行脱机存储或虚拟化的任何筛选器不因此打开而撤回文件的内容。 |
FILE_OPEN_FOR_FREE_SPACE_QUERY (0x00800000) | 此标志指示文件系统捕获与调用线程关联的用户。 使用返回的句柄对 FltQueryVolumeInformation 或 ZwQueryVolumeInformationFile 的任何后续调用都将假定捕获的用户,而不是当时的调用用户,以便计算调用方可用的可用空间。 这适用于以下 FsInformationClass 值: FileFsSizeInformation 、 FileFsFullSizeInformation 和 FileFsFullSizeInformationEx 。 |
NamedPipeType [in]
用于创建 (字节类型或消息类型) 的命名管道的类型。
ReadMode [in]
读取字节类型或消息类型) (管道的模式。
CompletionMode [in]
指定如何完成操作。
MaximumInstances [in]
命名管道同时实例的最大数目。
InboundQuota [in]
指定为写入命名管道的入站端保留的池配额。
OutboundQuota [in]
指定为写入命名管道的入站端保留的池配额。
DefaultTimeout [in, optional]
一个可选指针,指向在等待命名管道实例时未指定超时值时使用的超时值。
返回
函数值是创建/打开操作的最终状态。
备注
若要创建命名管道的实例,用户必须具有对命名管道对象的 FILE_CREATE_PIPE_INSTANCE 访问权限。 如果创建新的命名管道,则安全属性参数 (ACL) 访问控制列表定义命名管道的任意访问控制。
命名管道的所有实例必须指定相同的管道类型 (字节类型或消息类型) 、管道访问 (双工、入站或出站) 、实例计数和超时值。 如果使用不同的值,此函数将失败, GetLastError 将返回 ERROR_ACCESS_DENIED。
客户端进程使用 CreateFile 或 CallNamedPipe 函数连接到命名管道。 命名管道的客户端以字节模式启动,即使服务器端处于消息模式也是如此。 为了避免在接收数据时出现问题,请将客户端设置为消息模式。 若要更改管道的模式,管道客户端必须打开具有 GENERIC_READ 的只读管道,并 FILE_WRITE_ATTRIBUTES 访问权限。
在管道客户端启动之前,管道服务器不应执行阻止读取操作。 否则,可能会出现争用情况。 当初始化代码(如 C 运行时)需要锁定和检查继承的句柄时,通常会发生这种情况。
每次创建命名管道时,系统都会使用非分页池(内核使用的物理内存)创建入站和/或出站缓冲区。 可以创建的管道实例 (以及对象(如线程和进程) )的数量受可用非分页池的限制。 每个读取或写入请求都需要缓冲区中用于读取或写入数据的空间,以及用于内部数据结构的额外空间。
输入和输出缓冲区大小为公告。 为命名管道的每一端保留的实际缓冲区大小为系统默认值、系统最小值或最大值,或向上舍入到下一个分配边界的指定大小。 指定的缓冲区大小应足够小,以便进程不会耗尽非分页池,但要足够大,足以容纳典型请求。
每当发生管道写入操作时,系统首先会尝试根据管道写入配额为内存充电。 如果剩余的管道写入配额足以满足请求,则写入操作将立即完成。 如果剩余的管道写入配额太小而无法满足请求,系统将尝试使用为进程保留的非分页池来扩展缓冲区以容纳数据。 写入操作将阻塞,直到从管道读取数据,以便释放额外的缓冲区配额。 因此,如果指定的缓冲区大小太小,系统将根据需要增大缓冲区,但缺点是操作会阻塞。 如果操作重叠,则会阻止系统线程;否则,应用程序线程将被阻止。
若要释放命名管道使用的资源,应用程序应始终在不再需要句柄时关闭句柄,这可以通过调用 CloseHandle 函数或在与实例句柄关联的进程结束时完成。 请注意,命名管道的实例可能有多个与之关联的句柄。 关闭命名管道实例的最后一个句柄时,始终会删除命名管道的实例。
要求
要求 | 值 |
---|---|
标头 | ntioapi.h |
库 | ntdll.lib |