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 时可能会遇到的各种问题。 仅当专门引用存储在文件系统上实际文件中的数据时,文本才会尝试使用单词
使用 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) | 不 |
群集共享卷文件系统 (CsvFS) | 是的 |
可复原文件系统 (ReFS) | 是的 |
符号链接行为
如果对此函数的调用创建文件,则行为没有变化。 此外,请考虑以下有关在 pCreateExParams 参数-
如果指定了 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 标志指定为 dwFileFlagspCreateExParams 参数中传递 CREATEFILE2_EXTENDED_PARAMETERS 结构的一部分。 在没有 SE_BACKUP_NAME 和 SE_RESTORE_NAME 特权的情况下使用此标志时,仍适用适当的安全检查。
使用 CreateFile2 在对 FAT 或 FAT32 文件系统卷进行碎片整理期间打开目录时,请不要指定 MAXIMUM_ALLOWED 访问权限。 如果这样做,则拒绝对目录的访问。 请改为指定 GENERIC_READ 访问权限。
有关详细信息,请参阅 关于目录管理。
物理磁盘和卷
对磁盘或卷的直接访问受到限制。可以使用 CreateFile2 函数打开物理磁盘驱动器或卷,该驱动器返回可与 DeviceIoControl 函数一起使用的直接访问存储设备 (DASD) 句柄。 这样,便可以直接访问磁盘或卷,例如分区表等磁盘元数据。 但是,这种类型的访问还会向潜在的数据丢失公开磁盘驱动器或卷,因为使用此机制对磁盘进行不正确的写入可能会使其内容无法访问操作系统。 为了确保数据完整性,请务必熟悉 DeviceIoControl,以及其他 API 与直接访问句柄(而不是文件系统句柄)的行为方式不同。
必须满足以下要求才能成功进行此类调用:
- 调用方必须具有管理权限。 有关详细信息,请参阅 使用特殊特权运行。
- dwCreationDisposition 参数必须具有 OPEN_EXISTING 标志。
- 打开卷或软盘时,dwShareMode 参数必须具有 FILE_SHARE_WRITE 标志。
字符串 | 意义 |
---|---|
“\\.\PhysicalDrive0” | 打开第一个物理驱动器。 |
“\\.\PhysicalDrive2” | 打开第三个物理驱动器。 |
若要获取卷的物理驱动器标识符,请打开卷的句柄,并使用 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS调用 DeviceIoControl 函数。 此控制代码返回每个卷的一个或多个盘区的磁盘编号和偏移量;卷可以跨越多个物理磁盘。
有关打开物理驱动器的示例,请参阅 调用 DeviceIoControl。
打开卷或可移动媒体驱动器(例如软盘驱动器或闪存内存拇指驱动器)时,lpFileName 字符串应采用以下格式:“\\.\X:”。 不要使用尾随反斜杠(\),指示驱动器的根目录。 下表显示了驱动器字符串的一些示例。
字符串 | 意义 |
---|---|
“\\.\A:” | 打开软盘驱动器 A。 |
“\\.\C:” | 打开 C: 卷。 |
“\\.\C:\” | 打开 C: 卷的文件系统。 |
还可以通过引用卷名称来打开卷。 有关详细信息,请参阅 命名卷。
卷包含一个或多个装载的文件系统。 即使 CreateFile2中未指定非缓存选项,也可以以非缓存方式打开卷句柄。 应假定所有Microsoft文件系统都以非缓存的形式打开卷句柄。 对文件的非缓存 I/O 的限制也适用于卷。
即使数据未缓存,文件系统也可能不需要缓冲区对齐。 但是,如果在打开卷时指定了非缓存选项,则会强制实施缓冲区对齐方式,而不考虑卷上的文件系统。 建议在所有文件系统上以非缓存方式打开卷句柄,并遵循非缓存 I/O 限制。
变更程序设备
DeviceIoControl 的 IOCTL_CHANGER_* 控制代码 接受变更器设备的句柄。 若要打开更改器设备,请使用以下形式的文件名:“\\.\Changerx”,其中 x 是一个数字,指示要打开的设备,从零开始。 若要在用 C 或 C++ 编写的应用程序中打开 changer 设备零,请使用以下文件名:“\\.\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 打开控制台时,应指定 |
设置 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 之前,该函数将返回 INVALID_HANDLE_VALUE。有关详细信息,请参阅 Mailslots。
管道
如果 CreateFile2 打开命名管道的客户端端,该函数将使用处于侦听状态的命名管道的任何实例。 打开过程可以根据需要多次复制句柄,但在打开句柄后,命名管道实例无法由另一个客户端打开。 打开管道时指定的访问必须与 createNamedPipe 函数的如果在此操作之前未在服务器上成功调用 CreateNamedPipe 函数,则管道将不存在,并且 CreateFile2 失败,ERROR_FILE_NOT_FOUND。
如果至少有一个活动管道实例,但服务器上没有可用的侦听器管道,这意味着所有管道实例当前都已连接,CreateFile2 失败,ERROR_PIPE_BUSY。
有关详细信息,请参阅 管道。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows 8 [桌面应用 |UWP 应用] |
支持的最低服务器 | Windows Server 2012 [桌面应用 |UWP 应用] |
目标平台 | 窗户 |
标头 | fileapi.h (包括 Windows.h) |
库 | Kernel32.lib |
DLL | Kernel32.dll |
另请参阅
关于卷管理 的
Functions
概述主题