极语言官方网站

内核对象——本地文件系统

文件系统使应用程序能够在存储设备上存储和检索文件。 文件放置在分层结构中。

文件系统指定文件的命名约定和用于指定树结构中文件路径的格式。

每个文件系统由一个或多个驱动程序和动态链接库组成,用于定义文件系统的数据格式和功能。

文件系统可以存在于许多不同类型的存储设备上,包括硬盘、自动存储盒、可移动光盘、磁带备份单元和内存卡。

Windows 支持的所有文件系统都具有以下存储组件:
卷。 卷是目录和文件的集合。
目录。 目录是目录和文件的分层集合。
文件存储。 文件是相关数据的逻辑分组。


目录管理


目录是目录和文件的分层集合。 单个目录中可包含的文件数的唯一限制是目录所在的磁盘的物理大小。

包含一个或多个目录的目录是包含目录的 父 目录,每个包含目录都是父目录的 子 目录。 目录的分层结构称为 目录树。

NTFS文件系统实现目录与它作为目录 条目表包含的文件之间的逻辑链接。

将文件移动到目录中时,在表中创建条目并写入文件的名称。删除目录中包含的文件时,

也会从表中删除与已删除文件对应的名称和条目。 一个目录项表中可以存在单个文件的多个条目。

如果在表中为文件创建了其他条目,该条目称为指向该文件的 硬链接 。

可以为单个文件创建的硬链接数量没有限制。目录还可以包含交汇点和重新分析点。



创建和删除目录

应用程序可以编程方式创建和删除目录。

若要创建新目录,请使用 创建目录、 仿建目录 或 事务目录 函数。 目录在创建时为其指定的名称。

命名目录的约定遵循命名文件的约定。 有关这些约定的说明,请参阅 命名文件。

若要删除现有目录,请使用 删除目录 或 移除目录 函数。

在删除目录之前,必须确保目录为空,并且你具有该目录的删除访问权限。 若要执行后者,请调用 取安全符 函数。



目录句柄

每当进程创建或打开目录对象时,它都会收到该对象的句柄。

若要获取现有目录的句柄,请使用 0x02000000 标志调用 创建文件 函数。可以将目录句柄传递给以下函数。

函数说明
备份读取备份文件或目录,包括安全信息。
备份查找在最初使用 备份读取 或 备份写入 函数访问的数据流中向前查找。
备份写入还原使用 备份读取 备份的文件或目录。
开件属性检索指定文件的文件信息。
文件大小检索指定文件的大小(以字节为单位)。
文件日期检索创建文件或目录、上次访问和上次修改的日期和时间。
文件类型检索指定文件的文件类型。
目录变更检索描述指定目录中的更改的信息。
文件改时设置指定的文件或目录的创建、上次访问或上次修改的日期和时间。


重分析点

文件或目录可以包含 重新分析点,这是用户定义的数据的集合。

存储数据的应用程序和安装用于解释数据和处理文件的文件系统筛选器可以理解此数据的格式。

当应用程序设置重新分析点时,它将存储此数据,以及一个 重新分析标记,该标记唯一标识它正在存储的数据。

当文件系统打开具有重分析点的文件时,它会尝试查找与重新分析

标记标识的数据格式关联的文件系统筛选器。如果找到文件系统筛选器,筛选器将按照重分析数据的指示处理文件。

如果未找到文件系统筛选器,则文件打开操作将失败。

例如,重新分析点用于实现 NTFS 文件系统链接和微软远程存储服务器 (RSS) 。

RSS 使用管理员定义的一组规则将不常使用的文件移动到长期存储,例如磁带或光学介质。

它使用重新分析点在文件系统中存储有关文件的信息。

此信息存储在存根文件中,该文件包含一个重分析点,其数据指向实际文件现在所在的设备。

文件系统筛选器可以使用此信息来检索文件。重分析点还用于实现装载的文件夹。

以下限制适用于重新分析点:

可以为目录建立重分析点,但目录必须为空。
否则,NTFS 文件系统无法建立重新分析点。
此外,不能在包含重分析点的目录中创建目录或文件。
重分析点和扩展属性是互斥的。
当文件包含扩展属性时,NTFS 文件系统无法创建重新分析点,并且不能在包含重新分析点的文件上创建扩展属性。
重分析点数据(包括 标记和可选 GUID)不能超过 16 KB。
如果要放置在重分析点中的数据量超过此限制,则设置重分析点将失败。
任何给定路径上的重分析点数限制为 63 个。
注意: 根据重分析点的长度,可以降低限制。
例如,如果重分析点以完全限定的路径为目标,则限制变为 31。
Windows Serer 2003 和 Windows XP: 任何给定路径上的重分析点数限制为 31 个。


重新分析点标记

每个重分析点都有一个标识符标记,以便可以有效地区分不同类型的重新分析点,而无需检查重新分析点中的用户定义的数据。

系统使用一组预定义的标记和一系列为微软保留的标记。

如果在设置重新分析点时使用任何保留标记,操作将失败。

这些范围中未包含的标记不是保留标记,可供应用程序使用。

设置重新分析点时,必须标记要放置在重分析点中的数据。

建立重分析点后,如果新数据的标记与现有数据的标记不匹配,则新的设置操作将失败。

如果标记匹配,则设置操作将覆盖现有的重新分析点。

若要检索重新分析点标记,请使用 查找文件 函数。 如果 属性 成员包含 0x400 属性,则 预留1 成员指定重新分析点。

标记内容

重分析标记存储为 DWORD 值。 位定义某些属性,如下图所示。
   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  +-+-+-+-+-----------------------+-------------------------------+
  |M|R|N|R|     Reserved bits     |      Reparse tag value        |
  +-+-+-+-+-----------------------+-------------------------------+

低 16 位确定重新分析点的类型。 高 16 位保留 12 位供将来使用,4 位表示标记的特定属性以及重新分析点表示的数据。

下表描述了这些位。

说明
M微软 位。 如果设置了此位,则标记归 微软 所有。 所有其他标记必须对此位使用零。
R保留;对于所有非 微软 标记,必须为零。
N名称代理位。 如果设置了此位,则文件或目录表示系统中的另一个命名实体。


重新分析点和文件操作

若要确定文件系统是否支持重新分析点,请调用 取卷信息 函数并检查 0x80 位标志。

使用 硬件控制 函数可以设置、修改、获取和删除重新分析点。 下表描述了可以使用 硬件控制 执行的重新分析点操作。

操作说明
FSCTL_SET_REPARSE_POINT允许调用程序设置新的重新分析点,或修改现有的重新分析点。
FSCTL_GET_REPARSE_POINT获取存储在现有重分析点中的信息。
FSCTL_DELETE_REPARSE_POINT删除现有的重新分析点。

如果要修改、获取或删除重新分析点,则必须在文件中包含的操作中指定相同的重新分析标记。 否则,操作将失败。

如果要修改或删除重新分析点,还必须在文件中包含的操作中指定重新分析 GUID 。 否则,操作将失败。

若要确定文件或目录是否包含重新分析点,请使用 文件属性 函数。

如果文件或目录具有关联的重新分析点,则设置 0x400 属性。

若要覆盖现有的重分析点,而没有文件或目录的句柄,请使用 0x400调用 创建文件。

无论相应的文件系统筛选器是否已安装并正常工作,此标志都允许打开文件。

重新分析点 使文件系统行为不同于大多数 Windows 开发人员可能习惯的行为,

因此在编写处理文件的应用程序时注意这些行为对于旨在访问支持重分析点的文件系统的可靠可靠应用程序至关重要。

这些注意事项的范围将取决于特定重新分析点的特定实现和关联的文件系统筛选器行为,这些行为可由用户定义。

请考虑以下有关 NTFS 重新分析点实现的示例,其中包括装载的文件夹、链接文件和 微软 远程存储服务器:

使用文件流的备份应用程序在使用重分析点备份文件时,应在 WIN32_STREAM_ID结构中指定8。
如果文件是重分析点,则使用 创建文件 函数的应用程序应在打开文件时指定 0x400 标志。
对 文件进行碎片整理 的过程需要对重新分析点进行特殊处理。
病毒检测应用程序应搜索指示链接文件的重新分析点。
大多数应用程序应对已移动到长期存储的文件采取特殊操作,前提是仅通知用户检索文件可能需要一段时间。
OpenFileById 函数将打开文件或重新分析点,具体取决于0x400标志的使用。
符号链接作为重分析点,具有特定于它们的某些 编程注意事项 。
使用 USN_RECORD和READ_USN_JOURNAL_DATA 结构时,
用于读取更新序列号 (USN ) 更改日志记录的卷管理活动需要对重新分析点进行特殊处理。


更改当前目录

活动路径末尾的目录称为当前目录;它是活动应用程序启动的目录,除非已显式更改。

应用程序可以通过调用 当前目录 函数来确定当前目录。

有时需要使用 全路径名 函数来确保在应用程序需要时包含驱动器号。

应用程序可以通过调用 修改目录 函数来更改当前目录。

以下示例演示如何使用 当前目录 和 修改目录。

文本 内容[64];//申请一个64字节长度的文本

当前目录(64,内容);//把当前进程所在目录获取到内容变量,并指明长度为64

修改目录("D:\Sec");//修改当前进程工作目录为D:\Sec



列出目录中的文件

查找文件类 文件;;//申请一个查找文件类的变量,名为文件
程序段 遍历(目录)
	目录=查找文件(目录,文件)
	循环{
	发送消息(列表, 列表添加, 0,文件.名称)
	}(下个文件(目录,文件)=0)
	关闭查找(目录)
结束

//目录是程序段接收的目录地址参数

查找文件时提交目录地址和查找文件类,返回查找文件的句柄对象,把它保存到目录这个参数变量里

循环把文件.名称添加到列表框,直到下个文件返回结果为0时,停止循环

最后关闭查找的句柄对象:目录

程序段 按钮1_点击;//在按钮事件里调用遍历目录的函数

遍历("d:\sec\*.*");//遍历d:\sec\目录下的所有文件

结束



移动目录

若要将目录以及其中包含的文件和子目录移到另一个位置,请调用 文件复制、 传送文件 或 移动事务 函数。

传送文件 函数具有与 转移文件 相同的功能,只不过 传送文件 允许您指定一个回调例程来接收有关操作进度的通知。

移动事务 函数使你能够以事务处理操作的形式执行操作。

以下示例演示如何将 转移文件 函数与目录配合使用。

转移文件("d:\sec\code","d:\sec\源码",8);//把"d:\sec\code"里的文件移动到"d:\sec\源码"目录下

这里使用标志为8,就是等待文件转移完成之后才返回



获取目录更改通知

应用程序可以使用更改通知监视目录及其子目录的内容。

等待更改通知类似于对目录及其子目录(如有必要)挂起读取操作。

当正在监视的目录中发生更改时,读取操作将完成。

例如,每当受监视目录内的文件名更改时,应用程序都可以使用这些函数来更新目录列表。

应用程序可以使用 初改通知 函数指定触发更改通知的一组条件。

条件包括对文件名、目录名称、属性、文件大小、上次写入时间和安全性的更改。此函数还返回可以使用等待函数的句柄。

如果满足等待条件,可以使用 次改通知 提供通知句柄来等待后续更改。

但是,这些函数并不指示满足等待条件的实际更改。使用 停改通知 关闭通知句柄。

若要在通知中检索有关特定更改的信息,请使用 目录变更 函数。

此函数还可用于提供完成例程。若要跟踪卷上的更改,请参阅 更改日志

以下示例监视目录树的目录名称更改。 它还监视目录的文件名更改。

该示例使用 初改通知 函数创建两个通知句柄,并使用 等多对象 函数来等待句柄。

每当在树中创建或删除目录时,该示例都应更新整个目录树。

每当在目录中创建或删除文件时,本示例都应刷新目录。

整数 结果,监视[2];//申请一个返回结果的整数和监视的数组

监视[0]=初改通知("d:\sec\code\",假,1)//监视目录中的文件创建和删除。含子目录为假,条件=1文件名更改

监视[1]=初改通知("d:\sec\",真,2)//观察子目录创建和删除。含子目录为真,条件=2目录名或子目录名更改

循环{结果=等多对象(2,@监视,假,-1)//等待两个对象,超时=-1是无限等待

判断(结果)//文件目录有变动就会返回结果

为 0 次改通知(监视[0])//已在目录中创建、重命名或删除文件。这里可以显示变更并重新启动通知

为 1 次改通知(监视[1])//已创建、重命名或删除目录。这里可以显示变更并重新启动通知

否则 信息框(0,"超时或错误")//其它结果可能是发生错误,值为0x102是超时



文件管理

文件对象提供资源 (物理设备或位于物理设备上的资源表示形式,) 可由 I/O 系统管理。 与其他对象一样,它们支持共享资源,

它们具有名称,它们受基于对象的安全性保护,并且支持同步。 I/O 系统还支持从资源读取或写入资源。



文件和群集

文件是文件系统中用户可以访问和管理的数据单元。文件在其目录中必须具有唯一的名称。

由字节流组成,包含一组相关数据,以及一组属性,用于描述文件或文件中的数据。

文件的创建时间是文件属性的一个示例。

创建文件时,会创建一个未命名的默认流,以存储文件打开时写入该文件的所有数据。

还可以在 文件中创建其他流。这些附加流称为备用流。

文件属性不存储在包含文件数据的数据流中,而是存储在其他位置并由操作系统管理。

所有文件系统数据(包括系统启动代码和目录)都由 NTFS 文件系统存储在文件中。

其他文件系统将此信息存储在文件系统外部的磁盘区域中。将此信息存储在文件中的一个优点是

Windows 可以轻松查找、访问和维护信息。其他优点是,其中每个文件都可能受安全描述符的保护,

在部分磁盘损坏的情况下,它们可能会快速重定位到磁盘的更安全部分。

所有受支持的文件系统的基本存储单元都是 群集,它是一组扇区。

这使文件系统可以独立于硬件磁盘控制器设置的磁盘扇区大小来优化磁盘数据的管理。

如果要管理的磁盘很大,并且在单个操作中移动和组织大量数据,管理员可以调整群集大小以适应这种情况。



文件流

流是字节序列。 在 NTFS 文件系统中,流包含写入文件的数据,它提供了比特性和属性更多的关于文件的信息。

例如,可以创建包含搜索关键字的流,或者创建文件的用户帐户的标识。

与文件关联的每个流都有自己的分配大小、实际大小和有效数据长度:
分配大小是为流保留的磁盘空间量。
实际大小是调用方正在使用的字节数。
有效数据长度 (VDL) 是根据流的分配大小初始化的字节数。

每个流还维护自己的压缩、加密和稀疏状态。没有与流关联的文件时间。

当文件中的任何流更新时,文件的文件时间也会更新。

每个流维护机会锁。 每个流还维护共享模式。

当请求对文件的删除访问权限时,操作系统会检查文件中所有打开的流的删除访问权限。

如果另一个进程在没有 4 权限的情况下打开了一个流,则你无法打开该文件进行删除访问。

如果要复制的文件具有数据流,并且使用了网络重定向程序,

则仅当客户端同时具有读取权限和读取属性权限时,才能复制该文件。


流的命名约定

从 Windows shell 命令行指定时,流的全名是“文件名:流名称:流类型”,如下例所示:“myfile.dat:stream1:$DATA”。

对于文件名合法的任何字符对于流名称也是合法的,包括空格。

有关详细信息,请参阅命名文件。 流类型(也称为属性类型代码)在 NTFS 文件系统内部。

因此,用户无法创建新的流类型,但可以打开现有的 NTFS 文件系统类型。

流类型说明符值始终以美元符号 ($) 开头。 有关流类型的列表,请参阅下文。

默认情况下,默认数据流未命名。 要完全指定默认数据流,请使用“filename::$DATA”,其中 $DATA 是流类型。

这等效于“filename”。 你可以使用文件命名约定在文件中创建命名流。

请注意,“$DATA”是合法的流名称。 例如,名为“sample”的文件中名为“$DATA”的流的全名将是“sample:$DATA:$DATA”。

如果在同一个文件上创建了一个名为“bar”的流,它的全名将是“sample:bar:$DATA”。

在创建和处理文件名为单字符的文件时,请在文件名前加上句点和反斜杠 (.),或者使用完全限定的路径名。

这样做的原因是 Windows 会将单字符文件名视为驱动器号。

当使用相对路径指定驱动器号时,驱动器号与路径之间用冒号分隔。

如果单字符名称是驱动器号还是文件名存在歧义,

则如果冒号后面的字符串是有效路径,则 Windows 会假定它是驱动器号,即使驱动器号无效。



文件对象

文件对象 充当内核和用户模式进程与驻留在物理磁盘上的文件数据之间的逻辑接口。

文件对象包含写入文件的数据以及以下内核维护的属性集。

信息类型目的
文件名命名相应的物理文件。
当前字节偏移量本部分后面介绍的同步文件 I/O () 用于标识读取和写入操作的当前起始位置。
共享模式指定当初始进程仍在访问文件时,第二个进程是否可以打开文件进行读取、写入或删除访问。
I/O 模式指定初始进程是针对 同步 I/O 还是异步 I/O、缓存或未缓存的 I/O、顺序或随机 I/O 等打开文件。
指向设备对象的指针标识文件数据所在的物理设备。
指向卷参数块或 VPB 的指针标识文件数据所在的卷或分区。
指向节对象指针的指针标识描述 映射文件的根结构。
指向专用缓存映射的指针标识当前缓存的文件数据。


文件句柄

当某个进程使用 创建文件 函数打开文件时, 文件句柄 将与之关联,直到进程终止或使用 关闭对象 函数关闭句柄为止。

文件句柄用于标识许多函数调用中的文件。

每个文件句柄和文件对象通常对于打开文件的每个进程都是唯一的,

唯一的例外是复制进程持有的文件句柄,或者当子进程继承父进程的文件句柄时。

在这些情况下,这些文件句柄是唯一的,但可以看到单个共享文件对象。 有关复制进程保留的文件句柄的详细信息,请参阅 复制对象 。

请注意,虽然文件句柄通常对进程是专用的,但文件处理指向的文件数据不是。

共享同一文件的进程和线程必须同步其访问。多数情况进程通过其专用句柄池来标识文件。



文件指针

打开文件时,系统会将 文件指针 与默认流相关联。

此文件指针是一个 64 位偏移量值,用于指定要读取的下一个字节或接收写入的下一个字节的位置。

每次打开文件时,系统都会将文件指针放在文件开头,即偏移量零。

每个读取和写入操作都会按读取和写入的字节数来提升文件指针。

例如,如果文件指针位于文件的开头,并且请求了 5 个字节的读取操作,则文件指针将在读取操作后紧接在偏移量 5 处。

当读取或写入每个字节时,系统会推进文件指针。

还可以通过调用 文件定位 函数来重新定位文件指针。

当文件指针到达文件末尾并且应用程序尝试从文件读取时,不会发生错误,但不会读取任何字节。

因此,在没有错误的情况下读取零个字节意味着应用程序已到达文件的末尾。 写入零个字节没有任何作用。

应用程序可以使用 结尾文件 函数截断或扩展文件。

此函数将文件末尾设置为文件指针的当前位置。



群集和盘区

可以从两个不同的角度引用群集:在文件内和卷上。

文件中的任何群集都有一个 虚拟群集编号 (VCN) ,这是它与文件开头的相对偏移量。

例如,查找到群集大小的两倍,然后是读取,将返回从第三个 VCN 开始的数据。

(LCN) 的 逻辑群集编号 描述群集与卷中某个任意点的偏移量。

LPN 应仅视为序号或相对数字。 无法保证将逻辑群集映射到物理硬盘驱动器扇区。

盘区是连续群集的运行。 例如,假设一个由 30 个群集组成的文件记录在两个区中。

第一个区可能由 5 个连续群集组成,其余 25 个群集中的另一个。

不保证磁盘上与任何其他范围的任何关系。

例如,第一个盘区可能高于后续盘区的 LCN。



访问掩码格式

所有安全对象都使用下图所示 的访问掩码 格式来排列其访问权限。

访问掩码格式

在此格式中,低阶 16 位用于对象特定的访问权限,接下来的 8 位用于 标准访问权限,这适用于大多数类型的对象,

而 4 位高阶位用于指定每个对象类型可以映射到一组标准和对象特定权限的 通用访问权限 。

ACCESS_MASK数据类型是定义标准权限、特定权限和泛型权限的 DWORD 值。

这些权限用于 访问控制条目 (ACE) ,是指定请求或授予对对象的访问权限的主要方式。


含义
0 15特定权限。 包含特定于与掩码关联的对象类型的访问掩码。
16 23标准权限。 包含对象的标准访问权限。
24访问系统安全 (ACCESS_SYSTEM_SECURITY) 。 它用于指示对 SACL) (系统访问控制列表 的访问。 这种类型的访问要求调用进程具有 SE_SECURITY_NAME (管理审核和安全日志) 权限。 如果在审核访问 ACE 的访问掩码中设置了此标志, (成功或不成功的访问) ,则将审核 SACL 访问。
25允许的最大 (MAXIMUM_ALLOWED)
26 27保留。
28泛型所有 (GENERIC_ALL) 。
29泛型执行 (GENERIC_EXECUTE) 。
30泛型写入 (GENERIC_WRITE) 。
31泛型读取 (GENERIC_READ) 。

标准权限位(16 到 23)包含对象的标准访问权限,可以是以下预定义标志的组合。

标志含义
16DELETE删除访问权限。
17READ_CONTROL 读取对安全描述符的所有者、组和 任意访问控制列表 (DACL) 的访问权限。
18WRITE_DAC对 DACL 的写入访问权限。
19WRITE_OWNER对所有者的写入访问权限。
20同步同步访问。

标准访问权限

每种类型的安全对象都有一组访问权限,这些权限对应于特定于该对象类型的操作。

除了这些特定于对象的访问权限外,还有一组标准访问权限,这些权限对应于大多数安全对象类型通用的操作。

英文名称数值作用解释
DELETE0x10000删除对象的权限。
READ_CONTROL0x20000读取对象 安全描述符中的信息的权限,不包括 系统访问控制列表中 的信息 (SACL) 。
SYNCHRONIZE0x100000将对象用于同步的权限。 这使线程能够等待对象处于信号状态。 某些对象类型不支持此访问权限。
WRITE_DAC0x40000修改 自由访问控制列表 的权限 (DACL 在对象的安全描述符中) 。
WRITE_OWNER0x80000更改对象安全说明符中的所有者的权限。
以下是上面几个值的组合
STANDARD_RIGHTS_ALL0x1F0000合并 DELETE、READ_CONTROL、WRITE_DAC、WRITE_OWNER 和 SYNCHRONIZE 访问。
STANDARD_RIGHTS_EXECUTE0x20000当前定义为等于 READ_CONTROL。
STANDARD_RIGHTS_READ0x20000当前定义为等于 READ_CONTROL。
STANDARD_RIGHTS_REQUIRED0xF0000合并 DELETE、READ_CONTROL、WRITE_DAC 和 WRITE_OWNER 访问。
STANDARD_RIGHTS_WRITE0x20000当前定义为等于 READ_CONTROL。

通用访问权限

可以使用通用访问权限来指定打开对象句柄时所需的访问类型。 这通常比指定所有相应的标准和特定权限更简单。

英文名称数值作用解释
GENERIC_ALL0x10000000所有可能的访问权限
GENERIC_EXECUTE0x20000000执行访问权限
GENERIC_READ0x80000000读取权限
GENERIC_WRITE0x40000000写入权限

文件访问权限常量

文件和目录的有效访问权限包括标准访问权限。 下表列出了特定于文件和目录的访问权限。

英文名称数值作用解释
FILE_ADD_FILE2对于目录,有权在目录中创建文件。
FILE_ADD_SUBDIRECTORY4对于目录,是创建子目录的权限。
FILE_ALL_ACCESS0x1F03FF文件的所有可能的访问权限。
FILE_APPEND_DATA4对于文件对象,是将数据追加到文件的权限。 (对于本地文件,如果未指定此标志,写入操作将不会覆盖现有数据 FILE_WRITE_DATA。) 对于目录对象,创建子目录 (的权限 FILE_ADD_SUBDIRECTORY) 。
FILE_CREATE_PIPE_INSTANCE4对于命名管道,是创建管道的权限。
FILE_DELETE_CHILD64 (0x40)对于目录,有权删除目录及其包含的所有文件,包括只读文件。
FILE_EXECUTE32 (0x20)对于本机代码文件,是执行该文件的权利。 授予脚本的此访问权限可能会导致脚本可执行,具体取决于脚本解释器。
FILE_LIST_DIRECTORY1对于目录,是列出目录内容的权限。
FILE_READ_ATTRIBUTES128 (0x80)读取文件属性的权利。
FILE_READ_DATA1对于文件对象,读取相应文件数据的权限。 对于目录对象,是读取相应目录数据的权限。
FILE_READ_EA8读取扩展文件属性的权利。
FILE_TRAVERSE32 (0x20)对于目录,是遍历目录的权限。 默认情况下,会向用户分配 BYPASS_TRAVERSE_CHECKING权限,这会忽略 FILE_TRAVERSE访问权限。 有关详细信息,请参阅 文件安全和访问权限 中的备注。
FILE_WRITE_ATTRIBUTES256 (0x100)写入文件属性的权利。
FILE_WRITE_DATA2对于文件对象,是将数据写入文件的权限。 对于目录对象,在目录中创建文件的权限 (FILE_ADD_FILE) 。
FILE_WRITE_EA16 (0x10)写入扩展文件属性的权利。
STANDARD_RIGHTS_READ0x20000包括 READ_CONTROL,这是读取文件或目录对象的安全描述符中信息的权限。 这不包括 SACL 中的信息。
STANDARD_RIGHTS_WRITE0x20000与 STANDARD_RIGHTS_READ 相同。

文件安全和访问权限
英文名称数值作用解释
FILE_GENERIC_EXECUTE0x1200A0FILE_EXECUTE|FILE_READ_ATTRIBUTES|STANDARD_RIGHTS_EXECUTE|SYNCHRONIZE
FILE_GENERIC_READ0x120089FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|STANDARD_RIGHTS_READ|SYNCHRONIZE
FILE_GENERIC_WRITE0x120116FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_DATA|FILE_WRITE_EA|STANDARD_RIGHTS_WRITE|SYNCHRONIZE

文件属性类型
英文名称数值作用解释
FILE_ATTRIBUTE_READONLY1 (0x00000001)只读文件。 应用程序可以读取文件,但不能写入或删除该文件。 在目录上不遵循此属性。 有关详细信息,请参阅 无法在 Windows Server 2003、Windows XP、Windows Vista 或 Windows 7 中查看或更改文件夹的只读或系统属性。
FILE_ATTRIBUTE_HIDDEN2 (0x00000002)文件或目录处于隐藏状态。 它不包括在普通目录列表中。
FILE_ATTRIBUTE_SYSTEM4 (0x00000004)操作系统使用其中的一部分或独占使用的文件或目录。
FILE_ATTRIBUTE_DIRECTORY16 (0x00000010)标识目录的句柄。
FILE_ATTRIBUTE_ARCHIVE32 (0x00000020)作为存档文件或目录的文件或目录。 应用程序通常使用此属性来标记要备份或删除的文件。
FILE_ATTRIBUTE_DEVICE64 (0x00000040)此值保留供系统使用。
FILE_ATTRIBUTE_NORMAL128 (0x00000080)未设置其他属性的文件。 此属性仅在单独使用时才有效。
FILE_ATTRIBUTE_TEMPORARY256 (0x00000100)用于临时存储的文件。 如果有足够的缓存内存可用,文件系统会避免将数据写回到大容量存储,因为通常情况下,应用程序在句柄关闭后会删除临时文件。 在这种情况下,系统可以完全避免写入数据。 否则,在句柄关闭后写入数据。
FILE_ATTRIBUTE_SPARSE_FILE512 (0x00000200)是稀疏文件的文件。
FILE_ATTRIBUTE_REPARSE_POINT1024 (0x00000400)具有关联的重新分析点的文件或目录,或作为符号链接的文件。
FILE_ATTRIBUTE_COMPRESSED2048 (0x00000800)压缩的文件或目录。 对于文件,将压缩该文件中的所有数据。 对于目录,压缩是新建文件和子目录的默认设置。
FILE_ATTRIBUTE_OFFLINE4096 (0x00001000)文件的数据不会立即可用。 此属性指示文件数据以物理方式移动到脱机存储。 此属性由远程存储(分层存储管理软件)使用。 应用程序不应随意更改此属性。
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED8192 (0x00002000)内容索引服务不会为文件或目录编制索引。
FILE_ATTRIBUTE_ENCRYPTED16384 (0x00004000)加密的文件或目录。 对于文件,文件中的所有数据流都已加密。 对于目录,加密是新创建的文件和子目录的默认加密。
FILE_ATTRIBUTE_INTEGRITY_STREAM32768 (0x00008000)目录或用户数据流配置了完整性 (仅在 ReFS 卷) 上受支持。 它不包括在普通目录列表中。 如果文件已重命名,完整性设置将一直保留。 如果复制了某个文件,则如果源文件或目标目录设置了完整性,则目标文件将具有完整性设置。在Windows Server 2012之前,不支持此标志。
FILE_ATTRIBUTE_VIRTUAL65536 (0x00010000)此值保留供系统使用。
FILE_ATTRIBUTE_NO_SCRUB_DATA131072 (0x00020000)后台数据完整性扫描程序不读取的用户数据流 (AKA 清理器) 。 在目录上设置时,它仅提供继承。 此标志仅在 存储空间 和 ReFS 卷上受支持。 它不包括在普通目录列表中。在Windows 8和Windows Server 2012之前,不支持此标志。
FILE_ATTRIBUTE_EA262144 (0x00040000)具有扩展属性的文件或目录。重要: 此常量仅供内部使用。
FILE_ATTRIBUTE_PINNED524288 (0x00080000)此属性指示用户意图,即即使未主动访问文件或目录,也应在本地保持完全存在。 此属性用于分层存储管理软件。
FILE_ATTRIBUTE_UNPINNED1048576 (0x00100000)此属性指示,除非主动访问文件或目录,否则不应在本地完全存在。 此属性用于分层存储管理软件。
FILE_ATTRIBUTE_RECALL_ON_OPEN262144 (0x00040000)此属性仅出现在目录枚举类 (FILE_DIRECTORY_INFORMATION、FILE_BOTH_DIR_INFORMATION等) 中。 设置此属性时,这意味着文件或目录在本地系统上没有物理表示形式;项是虚拟的。 打开该项目的成本将比平常要高,例如,它会导致至少从远程存储中提取其中一部分。
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS4194304 (0x00400000)如果设置了此属性,则意味着文件或目录在本地未完全存在。 对于表示并非所有数据都位于本地存储 (的文件,例如,它可能稀疏,某些数据仍位于远程存储) 中。 对于目录,这意味着某些目录内容正在从另一个位置虚拟化。 读取文件/枚举目录的成本将比平常要高,例如,这会导致至少从远程存储中提取一些文件/目录内容。 只有内核模式调用方可以设置此位。文件系统微型筛选器低于 180000 – 189999高度范围 (FSFilter HSM 加载顺序组) 不得对设置了此属性的文件发出目标缓存读取或写入。 这可能会导致缓存污染和潜在的文件损坏。 有关详细信息,请参阅 处理占位符。

文件属性标志
英文名称数值作用解释
FILE_FLAG_BACKUP_SEMANTICS0x02000000正在为备份或还原操作打开或创建文件。 当进程具有 SE_BACKUP_NAME 和 SE_RESTORE_NAME 权限时,系统将确保调用进程替代文件安全检查。 有关详细信息,请参阅 更改令牌中的特权。
FILE_FLAG_DELETE_ON_CLOSE0x04000000文件在其所有句柄都关闭后立即被删除,其中包括指定的句柄和任何其他打开或重复的句柄。如果存在文件的现有打开句柄,则调用会失败,除非它们都以 FILE_SHARE_DELETE 共享模式打开。针对文件的后续打开请求将失败,除非指定 FILE_SHARE_DELETE 共享模式。
FILE_FLAG_NO_BUFFERING0x20000000正在打开文件或设备,没有系统缓存用于数据读取和写入。 此标志不会影响硬盘缓存或内存映射文件。
FILE_FLAG_OPEN_NO_RECALL0x00100000文件数据已请求,但应继续位于远程存储中。 不应将其传输回本地存储。 此标志供远程存储系统使用。
FILE_FLAG_OPEN_REPARSE_POINT0x00200000不会进行正常的 重分析点 处理; CreateFile 将尝试打开重新分析点。 打开文件时,无论控制重分析点的筛选器是否正常运行,都返回文件句柄。此标志不能与 CREATE_ALWAYS 标志一起使用。
FILE_FLAG_OVERLAPPED0x40000000正在为异步 I/O 打开或创建文件或设备。在此句柄上完成后续 I/O 操作时, OVERLAPPED 结构中指定的事件将设置为信号状态。如果指定了此标志,则文件可用于同时读取和写入操作。
FILE_FLAG_POSIX_SEMANTICS0x01000000将根据 POSIX 规则进行访问。 这包括允许多个具有名称的文件(仅在大小写上不同)用于支持该命名的文件系统。 使用此选项时请小心,因为为 MS-DOS 或 16 位 Windows 编写的应用程序可能无法访问使用此标志创建的文件。
FILE_FLAG_RANDOM_ACCESS0x10000000访问应是随机的。 系统可将此选项用作优化文件缓存的提示。如果文件系统不支持缓存的 I/O 且 FILE_FLAG_NO_BUFFERING,则此标志无效。
FILE_FLAG_SESSION_AWARE0x00800000正在使用会话感知打开文件或设备。 如果未指定此标志,则会话 0 中运行的进程无法打开每个会话 (设备,例如使用 RemoteFX USB 重定向) 的设备。 此标志对不在会话 0 中的调用方无效。 此标志仅在服务器版本的 Windows 上受支持。
FILE_FLAG_SEQUENTIAL_SCAN0x08000000访问旨在从头到尾按顺序进行。 系统可将此选项用作优化文件缓存的提示。如果读取隐藏 (即使用反向扫描) ,则不应使用此标志。如果文件系统不支持缓存的 I/O 且 FILE_FLAG_NO_BUFFERING,则此标志无效。
FILE_FLAG_WRITE_THROUGH0x80000000写入操作不会通过任何中间缓存,它们将直接转到磁盘。有关其他信息,请参阅本主题的 缓存行为 部分。

文件安全标志

SECURITY_SQOS_PRESENT 标志指定为 属性 的一部分时,它还可以包含以下一个或多个值。

英文名称数值作用解释
SECURITY_ANONYMOUS0在匿名模拟级别模拟客户端。
SECURITY_CONTEXT_TRACKING0x40000安全跟踪模式是动态的。 如果未指定此标志,则安全跟踪模式为静态。
SECURITY_DELEGATION0x30000在委派模拟级别模拟客户端。
SECURITY_EFFECTIVE_ONLY0x80000服务器只能使用客户端安全上下文中已启用的方面。
SECURITY_IDENTIFICATION0x10000在标识模拟级别模拟客户端。
SECURITY_IMPERSONATION0x20000在模拟级别模拟客户端。 如果未将其他标志与 SECURITY_SQOS_PRESENT 标志一起指定,则这是默认行为。
SECURITY_SQOS_PRESENT0x00100000SECURITY_SQOS_PRESENT
SECURITY_VALID_SQOS_FLAGS0x001F0000SECURITY_VALID_SQOS_FLAGS

文件共享模式
英文名称数值作用解释
00x00000000阻止其他进程在请求删除、读取或写入访问权限时打开文件或设备。
FILE_SHARE_DELETE0x00000004启用文件或设备上的后续打开操作以请求删除访问权限。否则,如果其他进程请求删除访问权限,则无法打开文件或设备。
FILE_SHARE_READ0x00000001启用文件或设备上的后续打开操作以请求读取访问权限。否则,如果其他进程请求读取访问权限,则无法打开文件或设备。
FILE_SHARE_WRITE0x00000002启用文件或设备上的后续打开操作以请求写入访问权限。否则,如果其他进程请求写入访问权限,则无法打开文件或设备。

文件创建方式
英文名称数值作用解释
CREATE_ALWAYS2始终创建新文件。如果指定的文件存在且可写,则函数将截断文件,函数成功,最后错误代码设置为 ERROR_ALREADY_EXISTS (183) 。否则为0
CREATE_NEW1仅当文件尚不存在时,才创建新文件。如果指定的文件存在,则函数将失败,最后一个错误代码设置为 ERROR_FILE_EXISTS (80) 。否则会创建一个新文件。
OPEN_ALWAYS4始终打开文件。如果指定的文件存在,则函数成功,并将最后一个错误代码设置为 ERROR_ALREADY_EXISTS (183) 。否则为0
OPEN_EXISTING3仅当文件或设备存在时才打开它。如果指定的文件或设备不存在,则函数将失败,并将最后一个错误代码设置为 ERROR_FILE_NOT_FOUND (2) 。
TRUNCATE_EXISTING5打开一个文件并截断它,使其大小为零字节,仅当它存在时。如果指定的文件不存在,则函数将失败,最后一个错误代码设置为 ERROR_FILE_NOT_FOUND (2) 。

文件系统——相关函数
中文名称英文名称示例作用
目录管理
创建目录CreateDirectoryA创建目录(目录名,0)创建一个文件夹
仿建目录CreateDirectoryExA仿建目录(模板,目录名,安全)使用指定模板目录的属性创建新目录。新目录保留指定模板目录的其他属性。
事务目录CreateDirectoryTransactedA事务目录(模板,目录名,安全,事务)使用指定模板目录的属性,以事务处理操作的形式创建新目录。
停改通知FindCloseChangeNotification停改通知(通知)停止更改通知句柄监视。
初改通知FindFirstChangeNotificationA初改通知(目录名,含子目录,条件)创建更改通知句柄并设置初始更改通知筛选条件
次改通知FindNextChangeNotification次改通知(通知)请求操作系统在下次检测到相应更改时,发出更改通知句柄信号。
当前目录GetCurrentDirectoryA当前目录(长度,内容)获得当前进程的所在目录
修改目录SetCurrentDirectoryA修改目录(目录名)修改当前进程运行的目录
目录变更ReadDirectoryChangesW目录变更(监视,@数据,大小,子,条件,@已收,重叠类,回调)检索描述指定目录中更改的信息。函数不会报告对指定目录本身的更改。
目录更改ReadDirectoryChangesExW目录更改(监视,@数据,大小,子,条件,@已收,重叠类,回调,类型)检索描述指定目录中更改的信息。函数不会报告对指定目录本身的更改。
删除目录RemoveDirectoryA删除目录(目录)删除现有空目录,有文件不能删除
移除目录RemoveDirectoryTransactedA移除目录(目录,事务)删除现有的空目录作为事务处理操作。
备份读取BackupRead备份读取(文件,缓冲,长度,@已读,完成,访表,数据)将与指定文件或目录关联的数据读入缓冲区,可将数据写入备份介质。
备份查找BackupSeek备份查找(文件,低位,高位,@收低,@收高,数据)在使用备份数据时访问的数据流中查找转发。
备份写入BackupWrite备份写入(文件,缓冲,长度,@已读,完成,访表,数据)将与指定文件或目录关联的数据读入缓冲区,可将数据写入备份介质。
文件管理
文件读_hread文件读(文件,内容,长度)返回实际读取的字节数。
文件写_hwrite文件写(文件,内容,长度)返回实际写入的字节数
建文件_lcreat文件=建文件("12.txt",属性)创建或打开指定的文件,属性:0读写,1只读,2隐藏,4系统
开文件_lopen文件=开文件("34.txt",方式)打开现有文件,方式:0=读,1=写,2=读写
关文件_lclose关文件(文件)关闭指定的文件
读文件_lread已读=读文件(文件,内容,长度)返回实际读取的字节数。
写文件_lwrite已写=写文件(文件,内容,长度)返回实际写入的字节数
流定位_llseek流定位(文件,位置,方向)方向0=开头,1=当前位置,2=文件结尾;文件长度=流定位(文件,0,2)
文件码页AreFileApisANSI文件码页确定文件 I/O 函数是使用 ANSI(非零)还是 OEM (0)字符集代码页。适用于 8 位控制台输入和输出操作。
取消操作CancelIo取消操作(文件)取消由指定文件的调用线程颁发的所有挂起输入和输出 (I/O) 操作。
取消传输CancelIoEx取消传输(文件,重叠类)标记指定文件句柄的任何未完成的 I/O 操作。
取消同步CancelSynchronousIo取消同步(线程)将指定线程发出的挂起同步 I/O 操作标记为已取消。
关闭对象CloseHandle关闭对象(对象)关闭文件、文件映射、进程、线程、安全和同步对象等
文件传送CopyFile2文件传送(名称1,名称2,复制文件类)将现有文件复制到新文件,并通过回调函数向应用程序通知此操作的进度。
复制文件CopyFileA复制文件("a.txt","b.txt",假)最后参数为真不覆盖已有文件
文件复制CopyFileExA文件复制(名称,新名,回调,附加,取消,标志)将现有文件复制到新文件,并通过回调函数通知应用程序其进度。
复制事务CopyFileTransactedA复制事务(名称,新名,回调,附加,取消,标志,事务)将现有文件作为事务处理操作复制到新文件,并通过回调函数通知应用程序其进度。
创建文件CreateFileA文件=创建文件(名,读写,共享,安全,方式,属性,模板)可打开或创建文件或者I/O设备,并返回可访问的句柄:控制台,通信资源 目录(只读),磁盘驱动器,文件,邮槽,管道。
创建硬链CreateHardLinkA创建硬链(新名,原名,0)在现有文件和新文件之间建立硬链接。
删除文件DeleteFileA删除文件(文件名)删除现有文件
关闭查找FindClose关闭查找(搜索)关闭指定的搜索句柄
查找文件FindFirstFileA搜索=查找文件(文件名,文件信息)查找指定目录下的文件
下个文件FindNextFileA下个文件(搜索,文件信息)查找该目录下一个文件
查寻文件FindFirstFileExA查寻文件(目录,级别,@数据,匹配,条件,选项)在目录中搜索具有与指定属性匹配的名称和属性的文件或子目录。
刷新文件FlushFileBuffers刷新文件(文件)清除指定文件的缓冲区,并将所有缓冲的数据写入文件
执行类型GetBinaryTypeA执行类型(文件名,@类别)判断文件是否可以执行,类别收到文件的类型.返回0不可执行
压缩大小GetCompressedFileSizeA大小=压缩大小(文件名,@长度)获取压缩文件的大小,未压缩为实际大小.长度为高32位,大小为低32位
文件属性GetFileAttributesA属性=文件属性(文件名)获得指定文件或目录的属性
文件大小GetFileSize大小=文件大小(文件,@长度)获取已打开文件的大小,长度为高32位,返回大小为低32位
文件日期GetFileTime文件日期(文件,@创建,@访问,@写入)获取已打开文件的各项日期,不需要的参数可以为0
文件类型GetFileTypet=文件类型(文件)返回指定文件的类型,0未知,1磁盘文件,2控制台,3管道
全路径名GetFullPathNameA长度=全路径名(文件名,长度,@路径,@名称)检索指定文件的完整路径和文件名。
长路径名GetLongPathNameA长度=长路径名(短名,@长名,长度)获取指定文件路径的长路径形式
短路径名GetShortPathNameA短路径名(长路径,@短路径,大小)检索指定路径的短路径形式。
文目属性GetFileAttributesExA文目属性(名称,0,@信息)检索指定文件或目录的属性。
开件属性GetFileInformationByHandle开件属性(文件,@信息)检索指定文件句柄的文件信息。
文件取名GetTempFileNameA文件取名(目录,前缀,唯一,@名称)创建临时文件的名称。如果唯一为零,文件存在会增加数字直到不存在。
临时目录GetTempPathA临时目录(大小,@目录)检索为临时文件指定的目录的路径。
端口队列GetQueuedCompletionStatus端口队列(端口,@长度,@键值,@重叠类,超时)尝试从指定的 I/O 完成端口等待挂起取消对 I/O 完成数据包的排队。
端口发布PostQueuedCompletionStatus端口发布(端口,长度,键值,重叠类)将 I/O 完成数据包发布到 I/O 完成端口。
锁定文件LockFile锁定文件(文件,位置低,位置高,长度低,长度高)锁定打开文件中的区域。防止其他进程访问该区域
锁住文件LockFileEx锁住文件(文件,标志,0,长度低,长度高,重叠类)通过调用进程锁定指定的文件以供独占访问。标志:0共享锁,1不等待,2共享锁
解锁文件UnlockFile解锁文件(文件,位置低,位置高,长度低,长度高)解锁打开文件中的区域。允许其他进程访问该区域
解开文件UnlockFileEx解开文件(文件,0,长度低,长度高,重叠类)解锁打开文件中的区域。此函数可以同步或异步运行。
移动文件MoveFileA移动文件(原名,新名)原名文件不存在时,移动一个文件或目录,存在时改名.都存在或都不存在则出错
转移文件MoveFileExA转移文件(名称,新名,标志)使用各种移动选项移动现有文件或目录,包括其子级。
传送文件MoveFileWithProgressA传送文件(名称,新名,回调,附加,标志)移动文件或目录,包括其子级。可以提供接收进度通知的回调函数
移动事务MoveFileTransactedA移动事务(名称,新名,回调,附加,标志,事务)移动文件或目录包括其子级作为事务处理操作移动。可以提供接收进度通知的回调函数
打开文件OpenFile打开文件(名称,@信息,文件执行操作">操作)创建、打开、重新打开或删除文件。
读取文件ReadFile读取文件(文件,内容,长度,@已读,重叠类)从文件指针所指定的位置开始读取数据
读入文件ReadFileEx读入文件(文件,内容,长度,重叠类,回调)异步方式从文件指定的位置开始读取数据,通过指定完成例程报告可警报等待完成状态。
写入文件WriteFile写入文件(文件,内容,长度,@已读,重叠类)向文件指针所指定的位置开始写入数据
写出文件WriteFileEx写出文件(文件,内容,长度,重叠类,回调)异步方式向文件指定的位置开始写入数据,通过指定完成例程报告可警报等待完成状态。
修改属性SetFileAttributesA修改属性(路径,属性)修改指定文件或目录的属性
读文件组ReadFileScatter读文件组(文件,数组,大小,0,重叠类)从文件读取数据并将其存储在缓冲区数组中。
写文件组WriteFileGather写文件组(文件,数组,大小,0,重叠类)从缓冲区数组检索数据并将数据写入文件。
文件定位SetFilePointer文件定位(文件,位置,高位,方向)方向0开头,1当前,2结尾
文件改时SetFileTime文件改时(文件,创建时间,最后访问,上次写入)修改已打开文件的各项日期,不需要的参数可以为0
结尾文件SetEndOfFile结尾文件(文件)将指定文件的文件末尾(EOF)位置移动到文件指针的当前位置

坐标值
中文名字英文名称长度作用解释
坐标值COORD4用来存储16位坐标位置的信息
坐标值——成员表
中文英文类型作用解释
x整形水平坐标位置。
y整形垂直坐标位置。

查找文件类
中文名字英文名称长度作用解释
查找文件类FINDDATA318用来获取文件名称和时间等属性。
查找文件类——成员表
中文英文类型作用解释
属性dwFileAttributes整数表示文件的属性:$20(存档)、2(隐藏)、$80(正常)
1(只读)、$10(文件夹)、4(系统)$100(临时)
创建时间ftCreationTime.dwLowDateTime整数文件被创建的时间
创建高位ftCreationTime.dwHighDateTime整数创建时间的高位。
最后访问ftLastAccessTime.dwLowDateTime整数最后一次访问的时间
访问高位ftLastAccessTime.dwHighDateTime整数最后访问时间的高位
最后修改ftLastWriteTime.dwLowDateTime整数最后一次修改的时间
修改高位ftLastWriteTime.dwHighDateTime整数最后修改时间的高位
大小nFileSizeHigh整数文件大小的高位
长度nFileSizeLow整数文件大小的低位
预留1dwReserved0整数保留占位
预留2dwReserved1整数保留占位
名称cFileName文本260字节长度的文件名称
备用名cAlternateFileName文本14字节长度的备用文件名

文件传输回调
中文名字英文名称长度作用解释
文件传输回调LpoverlappedCompletionRoutine3当异步输入和输出 (I/O) 操作完成或取消,并且调用线程处于可警报状态
文件传输回调——参数表
状态dwErrorCode整数I/O 完成状态。
已传dwNumberOfBytesTransfered整数已传输的字节数。 如果发生错误,此参数为零。
数据lpOverlapped整数指向异步 I/O 函数指定的 重叠类 结构的指针。

复制进度
中文名字英文名称参数作用解释
复制进度CopyProgressRoutine 9 当复制或移动操作的一部分完成时,将调用它。
复制进度 参数表
中文英文类型作用解释
总大小TotalFileSize整数文件的总大小(以字节为单位)。
总传送TotalBytesTransferred整数自复制操作开始以来从源文件传输到目标文件的字节总数。
流大小StreamSize整数当前文件流的总大小(以字节为单位)。
流传送StreamBytesTransferred整数自复制操作开始以来,当前流中从源文件传输到目标文件的字节总数。
流号dwStreamNumber整数当前流的句柄。 首次调用时,流号为 1。
原因dwCallbackReason整数0=复制了数据文件的另一部分。1=另一个流已创建,即将复制。
源文件hSourceFile整数源文件的句柄。
目标hDestinationFile整数目标文件的句柄
附加hDestinationFile整数传递的附加参数
复制进度返回值
英文名称参数作用解释
PROGRESS_CANCEL1取消复制操作并删除目标文件。
PROGRESS_CONTINUE0继续复制操作。
PROGRESS_QUIET3继续复制操作,但停止调用 复制进度 来报告进度。
PROGRESS_STOP2停止复制操作。 它可以在以后重新启动。

文件属性类
中文名字英文名称长度作用解释
文件属性类WIN32_FILE_ATTRIBUTE_DATA32包含文件或目录的属性信息。
文件属性类——成员表
中文英文类型作用解释
属性dwFileAttributes整数表示文件的属性:$20(存档)、2(隐藏)、$80(正常)
1(只读)、$10(文件夹)、4(系统)$100(临时)
创建时间ftCreationTime.dwLowDateTime整数文件被创建的时间
创建高位ftCreationTime.dwHighDateTime整数创建时间的高位。
最后访问ftLastAccessTime.dwLowDateTime整数最后一次访问的时间
访问高位ftLastAccessTime.dwHighDateTime整数最后访问时间的高位
最后修改ftLastWriteTime.dwLowDateTime整数最后一次修改的时间
修改高位ftLastWriteTime.dwHighDateTime整数最后修改时间的高位
大小nFileSizeHigh整数文件大小的高位
长度nFileSizeLow整数文件大小的低位

开件属性类
中文名字英文名称长度作用解释
开件属性类BY_HANDLE_FILE_INFORMATION44包含文件或目录的属性信息。
开件属性类——成员表
中文英文类型作用解释
属性dwFileAttributes整数表示文件的属性:$20(存档)、2(隐藏)、$80(正常)
1(只读)、$10(文件夹)、4(系统)$100(临时)
创建时间ftCreationTime.dwLowDateTime整数文件被创建的时间
创建高位ftCreationTime.dwHighDateTime整数创建时间的高位。
最后访问ftLastAccessTime.dwLowDateTime整数最后一次访问的时间
访问高位ftLastAccessTime.dwHighDateTime整数最后访问时间的高位
最后修改ftLastWriteTime.dwLowDateTime整数最后一次修改的时间
修改高位ftLastWriteTime.dwHighDateTime整数最后修改时间的高位
大小nFileSizeHigh整数文件大小的高位
长度nFileSizeLow整数文件大小的低位
链接数nNumberOfLinks整数指向此文件的链接数。对于 FAT 文件系统,此成员始终为 1。对于 NTFS 文件系统,它可以超过 1。
标识高位nFileIndexHigh整数与文件关联的唯一标识符的高阶部分。
标识低位nFileIndexLow整数与文件关联的唯一标识符的低序部分。

可执行文件类型
英文名称数值作用解释
SCS_32BIT_BINARY0基于 32 位 Windows 的应用程序
SCS_64BIT_BINARY6基于 64 位 Windows 的应用程序。
SCS_DOS_BINARY1基于 MS-DOS 的应用程序
SCS_OS216_BINARY5基于 16 位 OS/2 的应用程序
SCS_PIF_BINARY3执行基于 MS-DOS 的应用程序的 PIF 文件
SCS_POSIX_BINARY4基于 POSIX 的应用程序
SCS_WOW_BINARY2基于 16 位 Windows 的应用程序

打开文件类
中文名字英文名称长度作用解释
打开文件类OFSTRUCT136包含有关 打开文件 函数打开的或尝试打开的文件的信息。
复制文件类——成员表
中文英文类型作用解释
大小cBytes字节结构的大小(以字节为单位)。
硬盘fFixedDisk字节如果此成员为非零,则该文件位于固定磁盘 (硬) 。 否则就不是架构拥有的。
错误nErrCode整形如果 打开文件 函数失败,则返回 MS-DOS 错误代码。
预留Reserved1整形保留值;请勿使用。
备用Reserved2整形保留值;请勿使用。
名称szPathName[OFS_MAXPATHNAME]文本文件的路径和文件名。

文件执行操作
英文名称数值作用解释
OF_CANCEL0x00000800已忽略。若要生成包含 “取消 ”按钮的对话框,请使用 OF_PROMPT。
OF_CREATE0x00001000创建新文件。如果文件存在,则将其截断为零, (0) 长度。
OF_DELETE0x00000200删除文件。
OF_EXIST0x00004000打开一个文件,然后将其关闭。使用它来测试文件是否存在。
OF_PARSE0x00000100填充 OFSTRUCT 结构,但不执行任何其他操作。
OF_PROMPT0x00002000如果请求的文件不存在,则显示一个对话框。对话框通知用户系统找不到文件,其中包含 “重试” 和“ 取消 ”按钮。 “ 取消 ”按钮指示 OpenFile 返回找不到文件的错误消息。
OF_READ0x00000000打开文件以供只读。
OF_READWRITE0x00000002使用读/写权限打开文件。
OF_REOPEN0x00008000使用重新打开缓冲区中的信息打开文件。
OF_SHARE_COMPAT0x00000000对于基于 MS-DOS 的文件系统,使用兼容模式打开文件,允许指定计算机上的任何进程打开文件任意次数。使用其他共享模式打开文件的其他工作失败。 此标志映射到 CreateFile 函数的|FILE_SHARE_READ FILE_SHARE_WRITE标志。
OF_SHARE_DENY_NONE0x00000040在不拒绝对其他进程的读取或写入访问权限的情况下打开文件。在基于 MS-DOS 的文件系统上,如果该文件已被任何其他进程以兼容模式打开,则函数将失败。此标志映射到 CreateFile 函数的|FILE_SHARE_READ FILE_SHARE_WRITE标志。
OF_SHARE_DENY_READ0x00000030打开文件并拒绝对其他进程的读取访问权限。在基于 MS-DOS 的文件系统上,如果文件已在兼容模式下打开,或者由任何其他进程进行读取访问,则函数将失败。此标志映射到 CreateFile 函数的 FILE_SHARE_WRITE 标志。
OF_SHARE_DENY_WRITE0x00000020打开文件并拒绝对其他进程的写入访问权限。在基于 MS-DOS 的文件系统上,如果某个文件已在兼容模式下打开,或者由任何其他进程进行写入访问,则函数将失败。此标志映射到 CreateFile 函数的 FILE_SHARE_READ 标志。
OF_SHARE_EXCLUSIVE0x00000010使用独占模式打开文件,并拒绝对其他进程的读/写访问。如果文件已以任何其他模式打开进行读/写访问,即使当前进程也是如此,则函数会失败。
OF_VERIFY0x00000400验证文件的日期和时间是否与之前打开的时间相同。这对于只读文件的额外检查非常有用。
OF_WRITE0x00000001只是为了进行写入访问而打开文件。

复制文件类
中文名字英文名称长度作用解释
复制文件类COPYFILE2_EXTENDED_PARAMETERS20包含文件或目录的属性信息。
复制文件类——成员表
中文英文类型作用解释
大小dwSize整数结构的大小(以字节为单位)。
标志dwCopyFlags整数包含零个或多个这些标志值的组合。
取消pfCancel整数如果在复制操作期间将此标志设置为 真 ,则取消复制操作。
回调pProgressRoutine整数回调函数的可选地址,每次复制文件的另一部分时调用该函数。
附加pvCallbackContext整数传递给回调函数的应用程序特定上下文信息的指针。

复制进度回调
中文名字英文名称参数作用解释
复制进度回调Pcopyfile2ProgressRoutine 2 与 CopyFile2 函数一起使用的应用程序定义回调函数。 当复制或移动操作的一部分完成时,将调用它。
复制进度回调 参数表
中文英文类型作用解释
信息pMessage整数指向 复制信息 结构的指针。
附加pvCallbackContext整数传递给回调函数的应用程序特定上下文信息的副本。

文件复制标志
英文名称数值作用解释
COPY_FILE_FAIL_IF_EXISTS0x00000001如果目标文件存在,则复制操作将立即失败。 如果存在具有目标名称的文件或目录,则 CopyFile2 函数调用将失败并出现 HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) 或 HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)。 如果还指定 了COPY_FILE_RESUME_FROM_PAUSE ,则仅当目标文件没有有效的重启标头时才会触发失败。
COPY_FILE_RESTARTABLE0x00000002如果再次使用相同的源文件名和目标文件名,则复制文件的方式可以重启。 速度较慢。
COPY_FILE_OPEN_SOURCE_FOR_WRITE0x00000004复制该文件,并打开源文件以获取写入访问权限。
COPY_FILE_ALLOW_DECRYPTED_DESTINATION0x00000008即使无法加密目标文件,也会尝试复制。
COPY_FILE_COPY_SYMLINK0x00000800如果源文件是符号链接,则目标文件也是指向与源符号链接相同的文件的符号链接。
COPY_FILE_NO_BUFFERING0x00001000复制是使用未缓冲的 I/O 执行的,绕过系统缓存资源。 对于非常大的文件副本,建议使用此标志。 不建议暂停使用此标志的副本。
COPY_FILE_REQUEST_SECURITY_PRIVILEGES0x00002000尝试复制,并指定 ACCESS_SYSTEM_SECURITY 源文件和 ACCESS_SYSTEM_SECURITY \| WRITE_DAC \| WRITE_OWNER 目标文件。 如果拒绝这些请求,则访问请求将降低到授予访问权限的最高特权级别。 有关详细信息,请参阅 SACL 访问权限。 这可用于允许 CopyFile2ProgressRoutine 回调执行需要更高特权的操作,例如复制文件的安全属性。
COPY_FILE_RESUME_FROM_PAUSE0x00004000检查目标文件以查看它是否使用 COPY_FILE_RESTARTABLE复制。 如果是这样,则恢复复制。 否则,将完全复制文件。
COPY_FILE_NO_OFFLOAD0x00040000请勿尝试使用 Windows 复制卸载机制。 通常不建议这样做。
COPY_FILE_IGNORE_EDP_BLOCK0x00400000如果目标文件系统支持,则应在目标上复制和加密文件,而不是阻止该文件。 在 Windows 10 及更高版本上受支持。
COPY_FILE_IGNORE_SOURCE_ENCRYPTION0x00800000忽略源文件的加密状态。 在 Windows 10 及更高版本上受支持。
COPY_FILE_DONT_REQUEST_DEST_WRITE_DAC0x02000000不要请求目标文件访问WRITE_DAC。 在 Windows 10 及更高版本上受支持。
COPY_FILE_OPEN_AND_COPY_REPARSE_POINT0x00200000无论类型如何,始终复制重新分析点。 调用方有责任了解重新分析点的含义。 支持Windows 10版本 19041 及更高版本。
COPY_FILE_DIRECTORY0x00000080指示源文件是目录文件。 如果提供 ,则使用 FILE_OPEN_FOR_BACKUP_INTENT打开源文件。 目录文件将具有其备用数据流、重新分析点信息和像普通文件一样复制的 CA。 在 Windows 10 版本 19041 及更高版本中受支持。
COPY_FILE_SKIP_ALTERNATE_STREAMS0x00008000请勿复制备用数据流。 在 Windows 10 版本 19041 及更高版本中受支持。
COPY_FILE_DISABLE_PRE_ALLOCATION0x04000000在执行复制之前,请勿预先分配目标文件大小。 在 Windows 10 版本 19041 及更高版本中受支持。
COPY_FILE_ENABLE_LOW_FREE_SPACE_MODE0x08000000启用 LowFreeSpace 模式。 不使用重叠的 I/O。 不会尝试 ODX 和 SMB 卸载。 在 Windows 10 版本 19041 及更高版本中受支持。
COPY_FILE_REQUEST_COMPRESSED_TRAFFIC0x10000000请求基础传输通道在复制操作期间压缩数据。 并非所有媒体都支持请求,在这种情况下,它将被忽略。 压缩属性和参数 (计算复杂性、内存使用情况) 无法通过此 API 进行配置,并且可能会在不同的 OS 版本之间发生更改。 在 Windows Server 2022 和 Windows 10 内部版本 1903 及更高版本中受支持。 (Windows 10 上,驻留在 SMB 共享上的文件支持标志,其中协商的 SMB 协议版本为 SMB v3.1.1 或更高版本。)
COPY_FILE_ENABLE_SPARSE_COPY0x20000000在复制期间启用保留文件的稀疏状态。 在 Windows 11 版本 22H2 及更高版本中受支持。

重叠类
中文名字英文名称长度作用解释
重叠类OVERLAPPED20包含用于异步 (或 重叠) 输入和输出 (I/O) 的信息。
重叠类 成员表
中文英文类型作用解释
状态Internal整数I/O 请求的状态代码。发出请求时,系统会将此成员设置为 STATUS_PENDING 以指示操作尚未启动。
长度InternalHigh整数为 I/O 请求传输的字节数。 如果请求完成且未出错,系统会设置此成员。
位置Offset整数启动 I/O 请求的文件位置的低顺序部分,由用户指定。
偏移OffsetHigh整数要启动 I/O 请求的文件位置的高序部分,由用户指定。
事件hEvent整数事件的句柄,该句柄将在操作完成后由系统设置为信号状态。

移动文件标志
英文名称数值作用解释
MOVEFILE_COPY_ALLOWED2如果要将文件移动到其他卷,该函数将使用 CopyFile 和 DeleteFile 函数模拟移动。 如果文件已成功复制到其他卷,并且无法删除原始文件,则函数会成功使源文件保持不变。 此值不能与 MOVEFILE_DELAY_UNTIL_REBOOT 一起使用。
MOVEFILE_CREATE_HARDLINK0x10保留供将来使用。
MOVEFILE_DELAY_UNTIL_REBOOT4 在重新启动操作系统之前,系统不会移动文件。 系统在执行 AUTOCHK 之后、创建任何分页文件之前立即移动文件。 因此,此参数使 函数能够从以前的启动中删除分页文件。 仅当进程位于属于管理员组或 LocalSystem 帐户的用户的上下文中时,才能使用此值。 此值不能与 MOVEFILE_COPY_ALLOWED一起使用。
MOVEFILE_FAIL_IF_NOT_TRACKABLE0x20 如果源文件是链接源,则函数失败,但在移动后无法跟踪该文件。 如果目标是使用 FAT 文件系统格式化的卷,则可能会出现这种情况。
MOVEFILE_REPLACE_EXISTING1 如果存在名为 lpNewFileName 的文件,则函数会将其内容替换为 lpExistingFileName 文件的内容,前提是满足有关访问控制列表 (ACL) 的安全要求。 有关详细信息,请参阅本主题的“备注”部分。 如果 lpNewFileName 命名现有目录,则报告错误。
MOVEFILE_WRITE_THROUGH8在磁盘上实际移动文件之前, 函数不会返回 。 设置此值可确保作为复制和删除操作执行的移动在函数返回之前刷新到磁盘。 刷新发生在复制操作结束时。 如果设置了 MOVEFILE_DELAY_UNTIL_REBOOT ,则此值无效。

复制文件标志
英文名称数值作用解释
COPY_FILE_ALLOW_DECRYPTED_DESTINATION0x00000008即使无法加密目标复制,复制加密文件也会成功。
COPY_FILE_COPY_SYMLINK0x00000800如果源文件是符号链接,则目标文件也是指向源符号链接所指向的同一文件的符号链接。
COPY_FILE_FAIL_IF_EXISTS0x00000001如果目标文件已存在,则复制操作会立即失败。
COPY_FILE_NO_BUFFERING0x00001000复制操作使用未缓冲的 I/O 执行,绕过系统 I/O 缓存资源。 建议用于非常大的文件传输。
COPY_FILE_OPEN_SOURCE_FOR_WRITE0x00000004复制该文件,并打开原始文件进行写入访问。
COPY_FILE_RESTARTABLE0x00000002复制进度在目标文件中跟踪,以防复制失败。
COPY_FILE_REQUEST_COMPRESSED_TRAFFIC0x10000000请求基础传输通道在复制操作期间压缩数据。

文件更改通知条件
英文名称数值作用解释
FILE_NOTIFY_CHANGE_FILE_NAME0x00000001对受监视的目录或子树中文件名的任意更改都会导致返回一个更改通知等待操作。 这些更改包括重命名、创建或删除文件名。
FILE_NOTIFY_CHANGE_DIR_NAME0x00000002受监视目录或子树中的任何目录名称更改都会导致更改通知等待操作返回。 更改包括创建或删除目录。
FILE_NOTIFY_CHANGE_ATTRIBUTES0x00000004对受监视的目录或子树中属性的任意更改都会导致返回一个更改通知等待操作。
FILE_NOTIFY_CHANGE_SIZE0x00000008对受监视的目录或子树中文件大小的任意更改都会导致返回一个更改通知等待操作。 仅当文件写入磁盘时,操作系统才会检测文件大小的更改。 对于使用大量缓存的操作系统,仅当缓存充分刷新时,才会进行检测。
FILE_NOTIFY_CHANGE_LAST_WRITE0x00000010对受监视的目录或子树中文件的上次写入时间的任意更改都会导致返回一个更改通知等待操作。 仅当文件写入磁盘时,操作系统才会检测上次写入时间的更改。 对于使用大量缓存的操作系统,仅当缓存充分刷新时,才会进行检测。
FILE_NOTIFY_CHANGE_SECURITY0x00000100监视目录或子树中的任何安全描述符更改都会导致更改通知等待操作返回。

文件查找级别
英文名称数值作用解释
FindExInfoStandard0检索标准属性信息集。数据返回查找文件类 结构。
FindExInfoBasic1不查询短文件名,从而提高了整体枚举速度。 数据返回查找文件类 结构和 备用名
FindExInfoMaxInfoLevel2此值用于验证。支持的值小于此值。

文件查找匹配
英文名称数值作用解释
FindExSearchNameMatch0搜索与指定文件名匹配的文件。条件参数为空
FindExSearchLimitToDirectories1如果文件系统支持目录筛选,则函数将搜索与指定名称匹配且也是目录的文件。否则会以无提示方式忽略此标志。条件参数为空
FindExSearchLimitToDevices2此筛选类型不可用。
FindExSearchMaxSearchOp3此值用于验证。不可用。

文件查找选项
英文名称数值作用解释
FIND_FIRST_EX_CASE_SENSITIVE1搜索区分大小写。
FIND_FIRST_EX_LARGE_FETCH2对目录查询使用更大的缓冲区,这可以提高查找操作的性能。
FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY4将结果限制为物理位于磁盘上的文件。 仅当存在文件虚拟化筛选器时,此标志才相关。

文件映射——使用示例

文件映射 是文件内容与进程的一部分虚拟地址空间的关联。

系统创建 文件映射对象 (也称为 节对象) 来维护此关联。

文件视图是进程用来访问文件内容的虚拟地址空间部分。

文件映射允许进程使用随机输入和输出 (I/O) 和顺序 I/O。

它还允许进程高效处理大型数据文件(如数据库),而无需将整个文件映射到内存中。

多个进程还可以使用内存映射文件来共享数据。

处理使用指针从文件视图读取和写入文件视图的过程,就像使用动态分配的内存一样。

使用文件映射可提高效率,因为文件驻留在磁盘上,但文件视图驻留在内存中。

进程还可以使用 虚拟保护 函数操作文件视图。

下图显示了磁盘上的文件、文件映射对象和文件视图之间的关系。

磁盘上的文件、文件映射对象和文件视图之间的关系。

磁盘上的文件可以是要映射到内存中的任何文件,也可以是系统页文件。

文件映射对象可以包含文件的全部或部分。 它由磁盘上的 文件提供支持。

这意味着,当系统交换文件映射对象的页时,对文件映射对象所做的任何更改都将写入文件。

当文件映射对象的页面交换回时,它们将从 文件还原。

文件视图可以包含文件映射对象的全部或部分内容。

一个进程通过文件视图操作文件。 进程可以为文件映射对象创建多个视图。

每个进程创建的文件视图驻留在该进程的虚拟地址空间中。

当进程需要来自当前文件视图中的某个文件部分的数据时,它可以取消映射当前文件视图,然后创建新的文件视图。

当多个进程使用相同的文件映射对象为本地文件创建视图时,数据是一致的。

也就是说,视图包含磁盘上文件的相同副本

如果要在多个进程之间共享内存,则文件不能驻留在远程计算机上。



创建文件映射对象

映射文件的第一步是通过调用 创建文件 函数打开文件。

若要确保其他进程无法写入映射的文件部分,应以独占访问权限打开文件。

此外,文件句柄应保持打开状态,直到进程不再需要文件映射对象。

获取独占访问权限的一种简单方法是在 创建文件 的 共享 参数中指定零。

映射文件 函数返回文件映射对象的句柄。创建文件视图时将使用此句柄,以便可以访问共享内存。

调用 映射文件 时,可以指定对象名称、要从文件映射的字节数,

以及映射内存的读/写权限。调用 映射文件 的第一个进程创建文件映射对象。

为现有对象调用 映射文件 的进程会收到现有对象的句柄。

可以通过调用 最后错误 函数来判断对 映射文件 的成功调用是否创建或打开了文件映射对象。

最后错误 将 0 返回到创建进程, 并将183 返回到后续进程。

如果访问标志与 创建文件 函数打开文件时指定的标志冲突, 映射文件 函数将失败。

例如,若要读取和写入文件,请执行以下操作:

在 创建文件 的 读写 参数中指定读(0x80000000)和写(0x40000000)值。0xC0000000

在 映射文件 的 页保护 参数中指定4值。

创建文件映射对象不会提交物理内存,只保留它。


文件映射大小

文件映射对象的大小与所映射的文件的大小无关。

但是,如果文件映射对象大于文件,系统会在 映射文件 返回之前扩展该文件。

如果文件映射对象小于文件,则系统仅映射文件中的指定字节数。

映射文件 的 高数 和 低数 参数允许您指定要从文件映射的字节数:

如果不希望文件大小更改 (例如,将只读文件映射) 时,请调用 映射文件 并为 高数 和 低数 指定零。

执行此操作会创建与文件完全相同的文件映射对象。

否则,必须计算或估计完成文件的大小,因为文件映射对象的大小是静态的;创建后,无法增加或减少其大小。

尝试以这种方式映射长度为零的文件失败,错误代码 为 1006。 程序应测试长度为零的文件,并拒绝此类文件。

由命名文件支持的文件映射对象的大小受磁盘空间限制。

文件视图的大小限制为未保留虚拟内存的最大可用连续块。

这最多为 2 GB 减去进程已保留的虚拟内存。

所选文件映射对象的大小控制了使用内存映射“查看”到文件的距离。

如果创建大小为 500 Kb 的文件映射对象,则无论文件大小如何,您都只能访问该文件的前 500 Kb。

由于创建更大的文件映射对象不会花费任何系统资源,

因此创建文件映射对象的大小 (将 映射文件 的 高数 和 低数 参数设置为零) 即使不希望查看整个文件。

系统资源的成本来自创建视图并访问它们。



创建文件视图

若要将数据从文件映射到进程的虚拟内存,必须创建文件的视图。

映射进程 和 映射空间 函数使用 映射文件 返回的文件映射对象句柄

在进程的虚拟地址空间中创建文件视图或文件的一部分。

如果访问标志与 映射文件 创建文件映射对象时指定的访问标志冲突,则这些函数失败。

映射进程 函数返回指向文件视图的指针。

通过取消引用 映射进程 中指定的地址范围内的指针,应用程序可以从文件读取数据并将数据写入文件。

写入文件视图会导致对文件映射对象进行更改。

对磁盘上的文件的实际写入由系统处理。

在写入文件映射对象时,实际上不会传输数据。

而是缓存大部分文件输入和输出 (I/O) 以提高一般系统性能。

应用程序可以通过调用 刷新映射 函数来替代此行为,以强制系统立即执行磁盘事务。

映射空间 函数的工作方式与 映射进程 函数完全相同,

只不过它允许进程在 基址 参数的虚拟地址空间中指定文件视图的基址。

如果指定地址没有足够的空间,则调用将失败。

因此,如果必须将文件映射到多个进程中的同一地址,则进程应协商相应的地址:

基址 参数必须是系统内存分配粒度的整数倍数,否则调用将失败。

若要获取系统的内存分配粒度,请使用 系统信息 函数,该函数填充 系统信息类 结构的成员。

应用程序可以从同一文件映射对象创建多个文件视图。

文件视图的大小可以不同于派生它所基于的文件映射对象,但它必须小于文件映射对象。

映射进程 的 高数 和 低数 参数指定的偏移量必须是系统分配粒度的倍数。



共享文件和内存

文件映射可用于在两个或多个进程之间共享文件或内存。

若要共享文件或内存,所有进程都必须使用同一文件映射对象的名称或句柄。

若要共享文件,第一个进程使用 创建文件 函数创建或打开文件。

接下来,它通过使用 映射文件 函数创建文件映射对象,指定文件句柄和文件映射对象的名称。

事件、信号量、互斥体、可等待计时器、作业和文件映射对象的名称共享同一命名空间。

因此, 如果 映射文件 和 打开映射 函数指定了由另一种类型的对象使用的名称,则它们将失败。

若要共享与文件无关的内存,进程必须使用 映射文件 函数,

并将 文件 参数指定为-1,而不是现有文件句柄,大小为零。

相应的文件映射对象访问系统分页文件支持的内存。

其他进程获取由第一个进程创建的文件映射对象的句柄的最简单方法是

使用 打开映射 函数并指定对象的名称。 这称为 命名共享内存。

如果文件映射对象没有名称,则进程必须通过继承或重复获取它的句柄。

有关继承和重复的详细信息,请参阅 继承

共享文件或内存的进程必须使用 映射进程 或 映射空间 函数创建文件视图。

它们必须使用信号灯、互斥体、事件或其他一些互斥技术来协调其访问。 有关详细信息,请参阅 同步。

在使用该共享文件映射对象的所有进程使用 关闭对象 函数关闭其句柄之前,不会销毁共享文件映射对象。



从文件视图读取和写入

若要从文件视图读取数据,请取消引用 映射进程 函数返回的指针,如以下示例所示。

从页面文件以外的文件视图读取或写入文件可能会导致 0xC0000006 异常。

例如,如果与服务器的连接断开,则访问驻留在远程服务器上的映射文件可能会生成异常。

由于磁盘已满、基础设备故障或内存分配失败,也可能发生异常。

为了防止输入和输出 (I/O) 错误导致的异常,所有访问内存映射文件的尝试都应包装在结构化异常处理程序中。

在收到 0xC0000006 时,请确保地址位于当前正在访问的映射中。

如果是,请正常恢复或失败;否则,不处理异常。



关闭文件映射对象

当进程完成文件映射对象后,它应通过使用每个文件视图的 取消映射 函数来销毁其地址空间中的所有文件视图。

取消映射文件的映射视图会使视图在进程的地址空间中占用的范围失效,并使该范围可用于其他分配。

它删除属于进程工作集的每个未映射虚拟页面的工作集条目,并减小进程的工作集大小。

未映射视图中修改的页面在共享计数达到零之前不会写入磁盘,或者换而言之,

直到从共享页面的所有进程的工作集中取消映射或剪裁这些页面。

即便如此,修改后的页面也会“懒洋洋地”写入磁盘:

也就是说,修改可以在内存中缓存,并在以后写入磁盘。 为了在电源故障或系统崩溃时最大程度地降低数据丢失的风险,

应用程序应使用 刷新映射 函数显式刷新修改后的页面。

当每个进程使用完文件映射对象并取消映射所有视图时,

它必须通过调用 关闭对象 关闭文件映射对象的句柄和磁盘上的文件。

即使有文件视图仍处于打开状态,这些对 关闭对象 的调用也会成功。

但是,将文件视图保留为映射会导致内存泄漏。


文件映射 ——相关函数
中文名称英文名称示例作用
关闭映射CloseProfileUserMapping关闭映射关闭所有与初始化文件映射有关的登记键的句柄
映射文件CreateFileMappingA映射文件(文件,安全,页保护,高数,低数,名称)为指定文件创建或打开命名或未命名的文件映射对象。
刷新映射FlushViewOfFile刷新映射(基址,长度)将文件映射视图中的字节范围写入磁盘。
映射进程MapViewOfFile映射进程(映射,访问,高数,低数,大小)将文件映射的视图映射到调用进程的地址空间。
映射空间MapViewOfFileEx映射空间(映射,访问,高数,低数,大小,基址)将文件映射的视图映射到调用进程的地址空间。
映射节点MapViewOfFileExNuma映射节点(映射,访问,高数,低数,大小,基址,节点)将映射的文件视图映射到调用进程的地址空间中,并指定物理内存的 NUMA 节点。
取消映射UnmapViewOfFile取消映射(基址)从调用进程的地址空间中取消映射文件的映射视图。
打开映射OpenFileMappingA打开映射(访问,继承,映射名)打开命名文件映射对象。

映射访问类型

对文件映射对象的访问类型,该对象确定页面的页面保护。

英文名称数值作用解释
此参数可以是以下值之一,也可以是多个值的按位 OR 组合。
FILE_MAP_ALL_ACCESS0xF001F映射文件的读/写视图。 文件映射对象必须已创建 PAGE_READWRITE 或 PAGE_EXECUTE_READWRITE 保护。
FILE_MAP_READ0x0004映射文件的只读视图。 尝试写入文件视图会导致访问冲突。创建文件映射对象时必须具有 PAGE_READONLY、 PAGE_READWRITE、 PAGE_EXECUTE_READ或 PAGE_EXECUTE_READWRITE 保护。
FILE_MAP_WRITE0x0002映射文件的读/写视图。 文件映射对象必须已创建 PAGE_READWRITE 或 PAGE_EXECUTE_READWRITE 保护。
使用按位 OR,可以将上述值与这些值组合在一起。
FILE_MAP_COPY1映射文件的写入时复制视图。 文件映射对象必须已使用 PAGE_READONLY、 PAGE_READ_EXECUTE、 PAGE_WRITECOPY、 PAGE_EXECUTE_WRITECOPY、 PAGE_READWRITE或 PAGE_EXECUTE_READWRITE 保护创建。 当进程写入写入时复制页时,系统会将原始页面复制到进程专用的新页。 新页面由分页文件提供支持。 对新页面的保护从写入时复制更改为读/写。 指定写入时复制访问权限时,系统将和进程提交费用用于整个视图,因为调用进程可能会写入视图中的每一页,从而使所有页面都成为私有页面。 新页面的内容永远不会写回到原始文件,并在取消映射视图时丢失。
FILE_MAP_LARGE_PAGES0x20000000从 Windows 10 版本 1703 开始,此标志指定应使用大页面支持映射视图。 视图的大小必须是 GetLargePageMinimum 函数报告的大型页面大小的倍数,并且文件映射对象必须已使用 SEC_LARGE_PAGES 选项创建。 如果为 lpBaseAddress 提供非 null 值,则该值必须是 GetLargePageMinimum 的倍数。
FILE_MAP_EXECUTE0x0020映射文件的可执行视图 (映射的内存可以作为代码) 运行。 创建文件映射对象时必须具有 PAGE_EXECUTE_READ、 PAGE_EXECUTE_WRITECOPY或 PAGE_EXECUTE_READWRITE 保护。 Windows Server 2003 和 Windows XP: 此值从 Windows XP SP2 和 Windows Server 2003 SP1 开始可用。
FILE_MAP_TARGETS_INVALID0x40000000将映射文件中的所有位置设置为控制流防护 (CFG) 的无效目标。 此标志类似于 PAGE_TARGETS_INVALID。 将此标志与执行访问权限 FILE_MAP_EXECUTE结合使用。 对这些页面中的位置的任何间接调用都将失败 CFG 检查,并且进程将终止。 分配的可执行页面的默认行为是标记为 CFG 的有效调用目标。

页面保护类型
英文名称数值作用解释
PAGE_EXECUTE_READ0x20允许映射视图,以便进行只读、写入时复制或执行访问。必须使用GENERIC_READ创建 hFile 参数指定的文件句柄,并GENERIC_EXECUTE访问权限。
PAGE_EXECUTE_READWRITE0x40允许映射视图,以便进行只读、写入时复制、读/写或执行访问。必须使用GENERIC_READ、GENERIC_WRITE和GENERIC_EXECUTE访问权限创建 hFile 参数指定的文件句柄。
PAGE_EXECUTE_WRITECOPY0x80允许映射视图,以便进行只读、写入时复制或执行访问。必须使用 GENERIC_READ 创建 hFile 参数指定的文件句柄,并GENERIC_EXECUTE访问权限。
PAGE_READONLY0x02允许映射视图,以便进行只读或写入时复制访问。 尝试写入特定区域会导致访问冲突。必须使用GENERIC_READ访问权限创建 hFile 参数指定的文件句柄。
PAGE_READWRITE0x04允许映射视图,以便进行只读、写入时复制或读/写访问。必须使用 GENERIC_READ 创建 hFile 参数指定的文件句柄,GENERIC_WRITE访问权限。
PAGE_WRITECOPY0x08允许映射视图,以便进行只读或写入时复制访问。 此值等效于 PAGE_READONLY。必须使用GENERIC_READ访问权限创建 hFile 参数指定的文件句柄。

应用程序可以通过将以下属性与前面的页面保护值之一组合,为文件映射对象指定以下一个或多个属性。
英文名称数值作用解释
SEC_COMMIT0x8000000如果文件映射对象由操作系统分页文件提供支持, (hfile 参数 INVALID_HANDLE_VALUE) ,则指定当文件的视图映射到进程地址空间时,将提交而不是保留整个页面范围。 系统必须有足够的可提交页来保存整个映射。 否则, 映射文件 将失败。此属性对由可执行映像文件或数据文件支持的文件映射对象无效, (hfile 参数是文件) 的句柄。SEC_COMMIT 不能与 SEC_RESERVE 结合使用。
SEC_IMAGE0x1000000指定 hFile 参数指定的文件是可执行映像文件。SEC_IMAGE 属性必须与页面保护值(如 PAGE_READONLY)结合使用。 但是,此页面保护值对可执行文件的视图没有影响。 可执行文件的视图的页面保护由可执行文件本身决定。
SEC_IMAGE_NO_EXECUTE0x11000000指定 hFile 参数指定的文件是不会执行的可执行映像文件,并且加载的映像文件不会运行强制完整性检查。 此外,映射使用 SEC_IMAGE_NO_EXECUTE 属性创建的文件映射对象的视图不会调用使用 PsSetLoadImageNotifyRoutine 内核 API 注册的驱动程序回调。SEC_IMAGE_NO_EXECUTE 属性必须与PAGE_READONLY页保护值结合使用。 SEC_IMAGE_NO_EXECUTE中没有其他属性有效。在 Windows Server 2012 和 Windows 8 之前不支持此值。
SEC_LARGE_PAGES0x80000000允许将大型页面用于操作系统分页文件支持的文件映射对象, (hfile 参数 INVALID_HANDLE_VALUE) 。 由可执行映像文件或数据文件支持的文件映射对象不支持此属性, (hFile 参数是可执行映像或数据文件的句柄) 。文件映射对象的最大大小必须是 GetLargePageMinimum 函数返回的大页面最小大小的倍数。 否则, 映射文件 将失败。 映射使用 SEC_LARGE_PAGES 创建的文件映射对象的视图时,基址和视图大小也必须是最小大页面大小的倍数。
SEC_NOCACHE0x10000000将所有页面设置为不可缓存。除非设备明确需要,否则应用程序不应使用此属性。 将互锁函数 与SEC_NOCACHE映射 的内存结合使用可能会导致 EXCEPTION_ILLEGAL_INSTRUCTION 异常。SEC_NOCACHE 要求设置 SEC_RESERVE 或 SEC_COMMIT 属性。
SEC_RESERVE0x4000000如果文件映射对象由操作系统分页文件提供支持, (hfile 参数 INVALID_HANDLE_VALUE) ,则指定当文件的视图映射到进程地址空间时,将保留整个页面范围供进程以后使用,而不是提交。可以在后续调用 VirtualAlloc 函数时提交保留页。 提交页面后,无法使用 VirtualFree 函数释放或取消提交页面。此属性对由可执行映像文件或数据文件支持的文件映射对象无效, (hfile 参数是文件) 的句柄。SEC_RESERVE 不能与 SEC_COMMIT 结合使用。
SEC_WRITECOMBINE0x40000000将所有页面设置为写合并。除非设备明确需要,否则应用程序不应使用此属性。 将互锁函数 与SEC_WRITECOMBINE映射 的内存结合使用可能会导致 EXCEPTION_ILLEGAL_INSTRUCTION 异常。SEC_WRITECOMBINE 要求设置 SEC_RESERVE 或 SEC_COMMIT 属性。