CreateFile2 函数 (fileapi.h)
创建或者打开文件或 I/O 设备。 最常用的 I/O 设备如下:文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道。 函数返回一个句柄,该句柄可用于访问各种类型的 I/O 的文件或设备,具体取决于文件或设备以及指定的标志和属性。
从 Windows 应用商店应用调用时, CreateFile2 将简化。 只能打开 ApplicationData.LocalFolder 或 Package.InstalledLocation 目录中的文件或目录。 无法打开命名管道或 mailslot,也无法 (FILE_ATTRIBUTE_ENCRYPTED) 创建 加密文件。
语法
HANDLE CreateFile2(
[in] LPCWSTR lpFileName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in] DWORD dwCreationDisposition,
[in, optional] LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams
);
参数
[in] lpFileName
要创建或打开的文件或设备的名称。
有关特殊设备名称的信息,请参阅 定义 MS-DOS 设备名称。
若要创建文件流,请指定文件的名称、冒号,然后指定流的名称。 有关详细信息,请参阅 文件流。
[in] dwDesiredAccess
对文件或设备的请求访问权限,可汇总为读取、写入或两者均不为零) 。
最常用的值是 GENERIC_READ、 GENERIC_WRITE或两者 (GENERIC_READ | GENERIC_WRITE
) 。 有关详细信息,请参阅 通用访问权限、 文件安全性和访问权限、 文件访问权限常量和 ACCESS_MASK。
如果此参数为零,则应用程序可以在不访问该文件或设备的情况下查询某些元数据(如文件、目录或设备属性),即使 GENERIC_READ 访问被拒绝也是如此。
不能请求与已打开句柄的打开请求中的 dwShareMode 参数指定的共享模式冲突的访问模式。
有关详细信息,请参阅本主题的“备注”部分和 “创建和打开文件”。
[in] dwShareMode
请求的文件或设备的共享模式(可读取、写入、删除、所有这些共享模式或无 (请参阅下表) 。 对属性或扩展属性的访问请求不受此标志的影响。
如果此参数为零且 CreateFile2 成功,则在关闭文件或设备的句柄之前,无法共享文件或设备,并且无法再次打开。 有关详细信息,请参见“备注”部分。
不能请求与具有打开句柄的现有请求中指定的访问模式冲突的共享模式。 CreateFile2 将失败, GetLastError 函数将返回 ERROR_SHARING_VIOLATION。
若要使某个进程能够在另一个进程打开文件或设备时共享文件或设备,请使用以下一个或多个值的兼容组合。 有关此参数与 dwDesiredAccess 参数的有效组合的详细信息,请参阅 创建和打开文件。
[in] dwCreationDisposition
要对存在或不存在的文件或设备执行的操作。
对于文件以外的设备,此参数通常设置为 OPEN_EXISTING。
有关详细信息,请参见“备注”部分。
此参数必须是下列值之一,这些值不能合并:
[in, optional] pCreateExParams
指向可选 CREATEFILE2_EXTENDED_PARAMETERS 结构的指针。
返回值
如果函数成功,则返回值是指定文件、设备、命名管道或邮件槽的打开句柄。
如果函数失败,则返回值为 INVALID_HANDLE_VALUE。 要获得更多的错误信息,请调用 GetLastError。
注解
若要编译使用 CreateFile2 函数的应用程序,请将 _WIN32_WINNT 宏定义为 0x0602 或更高版本。 有关详细信息,请参阅 使用 Windows 标头。
CreateFile2 支持文件交互以及 Windows 开发人员可用的大多数其他类型的 I/O 设备和机制。 本部分尝试介绍开发人员在不同上下文和不同 I/O 类型中使用 CreateFile2 时可能遇到的各种问题。 仅当专门引用存储在文件系统上实际文件中的数据时,文本才会尝试使用单词 file 。 但是, 文件 的某些用途可能更一般地引用支持类似文件的机制的 I/O 对象。 由于前面提到的历史原因,这种对 术语文件 的自由使用在常量名称和参数名称中尤其普遍。
当应用程序使用 CreateFile2 返回的对象句柄完成时,请使用 CloseHandle 函数关闭该句柄。 这不仅释放了系统资源,而且对共享文件或设备以及将数据提交到磁盘等事项产生了更广泛的影响。 本主题中会根据需要说明具体内容。
某些文件系统(如 NTFS 文件系统)支持对单个文件和目录进行压缩或加密。 在具有具有此支持的已装载文件系统的卷上,新文件继承其目录的压缩和加密属性。
不能使用 CreateFile2 来控制文件或目录上的压缩、解压缩或解密。 有关详细信息,请参阅 创建和打开文件、 文件压缩和解压缩以及 文件加密。
如果 pCreateExParams 参数中传递的 CREATEFILE2_EXTENDED_PARAMETERS 结构的 lpSecurityAttributes 成员为 NULL,则应用程序可能创建的任何子进程都不能继承 CreateFile2 返回的句柄。 有关此成员的以下信息也适用:
- 如果 bInheritHandle 成员变量不是 FALSE(这是任何非零值),则可以继承句柄。 因此,如果不希望句柄可继承,则必须将此结构成员正确初始化为 FALSE 。
- 文件或目录的默认安全描述符中的访问控制列表 (ACL) 是从其父目录继承的。
- 目标文件系统必须支持文件和目录的安全性, lpSecurityDescriptor 成员才能对它们产生影响,这可以通过使用 GetVolumeInformation 确定。
技术 | 支持 |
---|---|
服务器消息块 (SMB) 3.0 协议 | 是 |
SMB 3.0 透明故障转移 (TFO) | 否 |
具有横向扩展文件共享的 SMB 3.0 (SO) | 否 |
群集共享卷文件系统 (CSV) | 是 |
弹性文件系统 (ReFS) | 是 |
符号链接行为
如果对此函数的调用创建了一个文件,则行为没有变化。 此外,请考虑以下有关 pCreateExParams 参数中传递的 CREATEFILE2_EXTENDED_PARAMETERS 结构的 dwFileFlags 成员的FILE_FLAG_OPEN_REPARSE_POINT标志的信息:-
如果指定 了FILE_FLAG_OPEN_REPARSE_POINT :
- 如果打开现有文件并且它是符号链接,则返回的句柄是符号链接的句柄。
- 如果指定 了TRUNCATE_EXISTING 或 FILE_FLAG_DELETE_ON_CLOSE ,则受影响的文件是符号链接。
-
如果未指定 FILE_FLAG_OPEN_REPARSE_POINT :
- 如果打开现有文件并且它是符号链接,则返回的句柄是目标的句柄。
- 如果指定 CREATE_ALWAYS、TRUNCATE_EXISTING 或 FILE_FLAG_DELETE_ON_CLOSE,则受影响的文件是目标。
文件
如果重命名或删除文件,然后在不久后还原它,系统会在缓存中搜索要还原的文件信息。 缓存的信息包括其短/长名称对和创建时间。如果对由于上次调用 DeleteFile 而正在等待删除的文件调用 CreateFile2,则函数将失败。 操作系统会延迟文件删除,直到文件的所有句柄都关闭。 GetLastError 返回 ERROR_ACCESS_DENIED。
dwDesiredAccess 参数可以为零,如果应用程序正在运行且具有足够安全设置,则允许应用程序在不访问文件的情况下查询文件属性。 这对于测试文件是否存在而不打开文件进行读取和/或写入访问,或者获取有关文件或目录的其他统计信息非常有用。 请参阅 获取和设置文件信息和GetFileInformationByHandle。
当应用程序通过网络创建文件时, GENERIC_READ | GENERIC_WRITE
最好将 用于 dwDesiredAccess ,而不是单独使用 GENERIC_WRITE 。 生成的代码速度更快,因为重定向程序可以使用缓存管理器,并发送更少的具有更多数据的 SMB。
此组合还避免了通过网络写入文件偶尔会返回 ERROR_ACCESS_DENIED的问题。
有关详细信息,请参阅创建和打开文件。
文件流
在 NTFS 文件系统上,可以使用 CreateFile2 在文件中创建单独的流。 有关详细信息,请参阅 文件流。目录
应用程序无法使用 CreateFile2 创建目录,因此对于此用例,只有 OPEN_EXISTING 值对 dwCreationDisposition 有效。 若要创建目录,应用程序必须调用 CreateDirectory 或 CreateDirectoryEx。若要使用 CreateFile2 打开目录,请将 FILE_FLAG_BACKUP_SEMANTICS 标志指定为 pCreateExParams 参数中传递的 CREATEFILE2_EXTENDED_PARAMETERS 结构的 dwFileFlags 成员的一部分。 在没有 SE_BACKUP_NAME 和 SE_RESTORE_NAME 特权的情况下使用此标志时,仍适用适当的安全检查。
在对 FAT 或 FAT32 文件系统卷进行碎片整理期间使用 CreateFile2 打开目录时,请不要指定 MAXIMUM_ALLOWED 访问权限。 如果执行此操作,将拒绝访问目录。 请改为指定 GENERIC_READ 访问权限。
有关详细信息,请参阅 关于目录管理。
物理磁盘和卷
对磁盘或卷的直接访问受到限制。可以使用 CreateFile2 函数打开物理磁盘驱动器或卷,这会返回直接访问存储设备 (DASD) 句柄,该句柄可与 DeviceIoControl 函数一起使用。 这使你能够直接访问磁盘或卷,例如分区表等磁盘元数据。 但是,这种类型的访问也会使磁盘驱动器或卷面临潜在的数据丢失,因为使用此机制对磁盘的错误写入可能会导致操作系统无法访问其内容。 若要确保数据完整性,请务必熟悉 DeviceIoControl ,以及其他 API 与直接访问句柄(而不是文件系统句柄)的行为方式不同。
必须满足以下要求,此类调用才能成功:
- 调用方必须具有管理权限。 有关详细信息,请参阅使用特殊特权运行。
- dwCreationDisposition 参数必须具有 OPEN_EXISTING 标志。
- 打开卷或软盘时, dwShareMode 参数必须具有 FILE_SHARE_WRITE 标志。
String | 含义 |
---|---|
“\\.\PhysicalDrive0” | 打开第一个物理驱动器。 |
“\\.\PhysicalDrive2” | 打开第三个物理驱动器。 |
若要获取卷的物理驱动器标识符,请打开卷的句柄,并使用 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS调用 DeviceIoControl 函数。 此控制代码返回每个卷的一个或多个盘区的磁盘编号和偏移量;卷可以跨多个物理磁盘。
有关打开物理驱动器的示例,请参阅 调用 DeviceIoControl。
打开卷或可移动媒体驱动器 (例如软盘驱动器或闪存 U 盘) 时, lpFileName 字符串应采用以下格式:“\.\X:”。 不要使用尾随反斜杠 (\) ,它指示驱动器的根目录。 下表显示了驱动器字符串的一些示例。
String | 含义 |
---|---|
“\\.\A:” | 打开软盘驱动器 A。 |
“\\.\C:” | 打开 C: 卷。 |
“\.\C:\” | 打开 C: 卷的文件系统。 |
还可以通过引用卷名称打开卷。 有关详细信息,请参阅 命名卷。
卷包含一个或多个装载的文件系统。 即使 CreateFile2 中未指定非缓存选项,也可以根据特定文件系统的判断将卷句柄作为非缓存打开。 应假定所有 Microsoft 文件系统都以未缓存的方式打开卷句柄。 对文件的非缓存 I/O 的限制也适用于卷。
即使数据未缓存,文件系统也可能不需要缓冲区对齐。 但是,如果在打开卷时指定了非缓存选项,则无论卷上的文件系统如何,都会强制实施缓冲区对齐。 建议在所有文件系统上以非缓存方式打开卷句柄,并遵循非缓存 I/O 限制。
更换器设备
DeviceIoControl的 IOCTL_CHANGER_* 控制代码接受变更器设备的句柄。 若要打开更换设备,请使用以下格式的文件名:“\\.\Changerx”,其中 x 是指示要打开的设备的数字,从零开始。 若要在用 C 或 C++ 编写的应用程序中打开更换设备零,请使用以下文件名:“\\\\.\Changer0”。磁带驱动器
可以使用以下格式的文件名打开磁带驱动器:“\\.\TAPEx”,其中 x 是指示要打开的驱动器的数字,从磁带驱动器零开始。 若要在用 C 或 C++ 编写的应用程序中打开磁带驱动器零,请使用以下文件名:“\\\\.\TAPE0”。有关详细信息,请参阅 备份。
通信资源
CreateFile2 函数可以创建通信资源的句柄,例如串行端口 COM1。 对于通信资源,dwCreationDisposition 参数必须是OPEN_EXISTING,dwShareMode 参数必须是零 (独占访问 ) ,hTemplateFile 参数必须为 NULL。 可以指定读取、写入或读/写访问权限,并且可以为重叠的 I/O 打开句柄。若要指定大于 9 的 COM 端口号,请使用以下语法:“\.\COM10”。 此语法适用于允许指定 COM 端口号的所有端口号和硬件。
有关通信的详细信息,请参阅 通信。
机
CreateFile2 函数可以创建控制台输入的句柄 (CONIN$) 。 如果进程由于继承或重复而具有打开的句柄,则它还可以 (CONOUT$) 创建活动屏幕缓冲区的句柄。 调用进程必须附加到继承的控制台或 AllocConsole 函数分配的控制台。 对于控制台句柄,请按如下所示设置 CreateFile2 参数。参数 | 值 |
---|---|
lpFileName |
使用 CONIN$ 值指定控制台输入。
使用 CONOUT$ 值指定控制台输出。 CONIN$ 获取控制台输入缓冲区的句柄,即使 SetStdHandle 函数重定向标准输入句柄也是如此。 若要获取标准输入句柄,请使用 GetStdHandle 函数。 CONOUT$ 获取活动屏幕缓冲区的句柄,即使 SetStdHandle 重定向标准输出句柄也是如此。 若要获取标准输出句柄,请使用 GetStdHandle。 |
dwDesiredAccess |
GENERIC_READ | GENERIC_WRITE 是首选,但两者都可以限制访问。
|
dwShareMode |
打开 CONIN$时,请指定 FILE_SHARE_READ。 打开 CONOUT$时,请指定 FILE_SHARE_WRITE。
如果调用进程继承控制台,或者子进程应能够访问控制台,则此参数必须为 |
dwCreationDisposition | 使用 CreateFile2 打开控制台时,应指定OPEN_EXISTING。 |
按如下所示设置 pCreateExParams 参数中传递的 CREATEFILE2_EXTENDED_PARAMETERS 结构的成员。
成员 | 值 |
---|---|
lpSecurityAttributes | 如果希望继承控制台,则 SECURITY_ATTRIBUTES 结构的 bInheritHandle 成员必须为 TRUE。 |
dwFileAttributes
dwFileFlags dwSecurityQosFlags hTemplateFile |
已忽略。 |
下表显示了 dwDesiredAccess 和 lpFileName 的各种设置。
lpFileName | dwDesiredAccess | 结果 |
---|---|---|
“CON” | GENERIC_READ | 打开控制台进行输入。 |
“CON” | GENERIC_WRITE | 打开控制台进行输出。 |
“CON” | GENERIC_READ | GENERIC_WRITE |
导致 CreateFile2 失败; GetLastError 返回 ERROR_FILE_NOT_FOUND。 |
Mailslots
如果 CreateFile2 打开 mailslot 的客户端端,则如果 mailslot 客户端在 mailslot 服务器使用 CreateMailSlot 函数创建本地 mailslot 之前尝试打开本地 mailslot,则函数将返回INVALID_HANDLE_VALUE。有关详细信息,请参阅 Mailslots。
管道
如果 CreateFile2 打开命名管道的客户端,则函数使用处于侦听状态的命名管道的任何实例。 打开进程可以根据需要多次复制句柄,但在打开该句柄后,其他客户端无法打开命名管道实例。 打开管道时指定的访问必须与 CreateNamedPipe 函数的 dwOpenMode 参数中指定的访问兼容。如果在此操作之前未在服务器上成功调用 CreateNamedPipe 函数,则管道将不存在, 并且 CreateFile2 将失败并 ERROR_FILE_NOT_FOUND。
如果至少有一个活动管道实例,但服务器上没有可用的侦听器管道,这意味着所有管道实例当前都已连接, 则 CreateFile2 将失败并 ERROR_PIPE_BUSY。
有关详细信息,请参阅 管道。
要求
最低受支持的客户端 | Windows 8 [桌面应用 |UWP 应用] |
最低受支持的服务器 | Windows Server 2012 [桌面应用 |UWP 应用] |
目标平台 | Windows |
标头 | fileapi.h (包括 Windows.h) |
Library | Kernel32.lib |
DLL | Kernel32.dll |
另请参阅
函数
概述主题
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈