CreateFileMappingW 函数 (memoryapi.h)
为指定文件创建或打开命名或未命名的文件映射对象。
若要为物理内存指定 NUMA 节点,请参阅 CreateFileMappingNuma。
语法
HANDLE CreateFileMappingW(
[in] HANDLE hFile,
[in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
[in] DWORD flProtect,
[in] DWORD dwMaximumSizeHigh,
[in] DWORD dwMaximumSizeLow,
[in, optional] LPCWSTR lpName
);
参数
[in] hFile
要从中创建文件映射对象的文件的句柄。
必须使用与 flProtect 参数指定的保护标志兼容的访问权限打开该文件。 这不是必需的,但建议打开要映射的文件进行独占访问。 有关详细信息,请参阅 文件安全和访问权限。
如果 INVALID_HANDLE_VALUEhFile,调用过程还必须在 dwMaximumSizeHigh 中指定文件映射对象的大小,并 dwMaximumSizeLow 参数。 在此方案中,CreateFileMapping 创建由系统分页文件而不是文件系统中的文件提供支持的指定大小的文件映射对象。
[in, optional] lpFileMappingAttributes
指向 SECURITY_ATTRIBUTES 结构的指针,该结构确定返回的句柄是否可以由子进程继承。 SECURITY_ATTRIBUTES 结构的 lpSecurityDescriptor 成员为新的文件映射对象指定安全描述符。
如果 lpAttributesNULL,则无法继承句柄,并且文件映射对象获取默认的安全描述符。 文件映射对象的默认安全描述符中的访问控制列表(ACL)来自创建者的主要或模拟令牌。 有关详细信息,请参阅 文件映射安全和访问权限。
[in] flProtect
指定文件映射对象的页面保护。 对象的所有映射视图都必须与此保护兼容。
此参数可以是下列值之一。
应用程序可以通过将它们与前面的页面保护值之一组合,为文件映射对象指定以下一个或多个属性。
价值 | 意义 |
---|---|
|
如果文件映射对象由操作系统分页文件(hfile 参数 INVALID_HANDLE_VALUE支持),则指定当文件的视图映射到进程地址空间时,将提交整个页面范围而不是保留。 系统必须有足够的可提交页面来保存整个映射。 否则,CreateFileMapping 失败。
此属性对由可执行图像文件或数据文件支持的文件映射对象无效(hfile 参数是文件的句柄)。 SEC_COMMIT 不能与 SEC_RESERVE结合使用。 如果未指定任何属性,则假定 SEC_COMMIT。 但是,在将 SEC_COMMIT 与需要 SEC_ 属性的另一个 SEC_ 属性组合在一起时,必须显式指定 SEC_COMMIT。 |
|
指定 hFile 参数指定的文件是可执行映像文件。
SEC_IMAGE 属性必须与页面保护值(如 PAGE_READONLY)结合使用。 但是,此页面保护值对可执行文件的视图没有影响。 可执行映像文件的视图的页面保护由可执行文件本身决定。 没有其他属性对 SEC_IMAGE有效。 |
|
指定 hFile 参数指定的文件是不会执行的可执行映像文件,并且加载的图像文件不会运行强制完整性检查。
此外,使用 SEC_IMAGE_NO_EXECUTE 属性创建的文件映射对象的视图不会调用使用 PsSetLoadImageNotifyRoutine 内核 API 注册的驱动程序回调。
SEC_IMAGE_NO_EXECUTE 属性必须与 PAGE_READONLY 页保护值结合使用。 没有其他属性对 SEC_IMAGE_NO_EXECUTE有效。 Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:Windows Server 2012 和 Windows 8 之前不支持此值。 |
|
使大型页面可用于操作系统分页文件支持的文件映射对象(hfile 参数 INVALID_HANDLE_VALUE)。 可执行文件或数据文件支持的文件映射对象不支持此属性(hFile 参数是可执行映像或数据文件的句柄)。
文件映射对象的最大大小必须是 GetLargePageMinimum 函数返回的大型页面的最小大小的倍数。 否则,CreateFileMapping 失败。 映射使用 SEC_LARGE_PAGES创建的文件映射对象的视图时,基址和视图大小也必须是最小大页面大小的倍数。 SEC_LARGE_PAGES 要求在调用方令牌中启用 SeLockMemoryPrivilege 特权。 如果指定了 SEC_LARGE_PAGES,还必须指定 SEC_COMMIT。 Windows Server 2003:Windows Server 2003 SP1 之前不支持此值。 Windows XP:不支持此值。 |
|
将所有页面设置为不可缓存。
应用程序不应使用此属性,除非设备明确需要时。 将互锁函数与与 SEC_NOCACHE 映射的内存配合使用可能会导致 EXCEPTION_ILLEGAL_INSTRUCTION 异常。 SEC_NOCACHE 要求设置 SEC_RESERVE 或 SEC_COMMIT 属性。 |
|
如果文件映射对象由操作系统分页文件(hfile 参数 INVALID_HANDLE_VALUE)提供支持,则指定当文件的视图映射到进程地址空间时,将保留整个页面范围供进程以后使用,而不是提交。
可以在对 VirtualAlloc 函数的后续调用中提交保留页。 提交页面后,无法使用 VirtualFree 函数释放或取消提交这些页面。 此属性对由可执行图像文件或数据文件支持的文件映射对象无效(hfile 参数是文件的句柄)。 SEC_RESERVE 不能与 SEC_COMMIT结合使用。 |
|
设置要组合写入的所有页面。
应用程序不应使用此属性,除非设备明确需要时。 将互锁函数与与 SEC_WRITECOMBINE 映射的内存配合使用可能会导致 EXCEPTION_ILLEGAL_INSTRUCTION 异常。 SEC_WRITECOMBINE 要求设置 SEC_RESERVE 或 SEC_COMMIT 属性。 Windows Server 2003 和 Windows XP:Windows Vista 之前不支持此标志。 |
[in] dwMaximumSizeHigh
文件映射对象的最大大小的高阶 DWORD。
[in] dwMaximumSizeLow
文件映射对象最大大小的低序 DWORD。
如果此参数和 dwMaximumSizeHigh 为 0(零),则文件映射对象的最大大小等于 hFile 标识的文件的当前大小。
尝试映射长度为 0(零)的文件失败,错误代码为 ERROR_FILE_INVALID。 应用程序应测试长度为 0(零)的文件,并拒绝这些文件。
[in, optional] lpName
文件映射对象的名称。
如果此参数与现有映射对象的名称匹配,函数将请求访问具有 flProtect
如果此参数 NULL,则创建文件映射对象时不带名称。
如果 lpName 与现有事件、信号灯、互斥体、可等待计时器或作业对象的名称匹配,则函数将失败,GetLastError 函数返回 ERROR_INVALID_HANDLE。 之所以发生这种情况,是因为这些对象共享相同的命名空间。
该名称可以具有“全局”或“本地”前缀,以在全局或会话命名空间中显式创建对象。 名称的其余部分可以包含除反斜杠字符(\)以外的任何字符。 从会话零以外的会话创建全局命名空间中的文件映射对象需要 SeCreateGlobalPrivilege 特权。 有关详细信息,请参阅 内核对象命名空间。
使用终端服务会话实现快速用户切换。 第一个登录的用户使用会话 0 (零),下一个登录的用户使用会话 1(一),依此等。 内核对象名称必须遵循终端服务概述的准则,以便应用程序能够支持多个用户。
返回值
如果函数成功,则返回值是新创建的文件映射对象的句柄。
如果在函数调用之前存在该对象,该函数将返回现有对象的句柄(其当前大小,而不是指定大小),GetLastError 返回 ERROR_ALREADY_EXISTS。
如果函数失败,则返回值 NULL。 若要获取扩展的错误信息,请调用 GetLastError。
言论
创建文件映射对象后,文件的大小不得超过文件映射对象的大小;如果存在,则并非所有文件内容都可用于共享。
如果应用程序指定的文件映射对象的大小大于磁盘上实际命名文件的大小,并且如果页面保护允许写入访问(即,flProtect 参数指定 PAGE_READWRITE 或 PAGE_EXECUTE_READWRITE),则磁盘上的文件将增加以匹配文件映射对象的指定大小。 如果文件已扩展,则文件旧端和文件新端之间的内容不保证为零;行为由文件系统定义。 如果磁盘上的文件无法增加,CreateFileMapping 失败,GetLastError 返回 ERROR_DISK_FULL。
操作系统分页文件支持的文件映射对象中页面的初始内容为 0(零)。
CreateFileMapping 返回的句柄对新的文件映射对象具有完全访问权限,并且可以与需要文件映射对象的句柄的任何函数一起使用。
多个进程可以使用单个共享文件映射对象或创建由同一文件支持的单独文件映射对象来共享同一文件的视图。 单个文件映射对象可以通过在创建进程时继承句柄、复制句柄或按名称打开文件映射对象,由多个进程共享。 有关详细信息,请参阅 CreateProcess、DuplicateHandle 和 OpenFileMapping 函数。
创建文件映射对象实际上不会将视图映射到进程地址空间。 MapViewOfFile 和 MapViewOfFileEx 函数将文件的视图映射到进程地址空间。
有一个重要例外,从由同一文件支持的任何文件映射对象派生的文件视图在特定时间是一致的或相同的。 对于进程内的视图和由不同进程映射的视图,可保证一致性。
异常与远程文件相关。 尽管 CreateFileMapping 适用于远程文件,但它不会使它们保持一致。 例如,如果两台计算机都将文件映射为可写文件,并且两台计算机都更改了同一页,则每台计算机只看到自己对页面的写入。 在磁盘上更新数据时,不会合并数据。
使用输入和输出(I/O)函数(ReadFile 和 WriteFile)访问的映射文件和文件不一定是一致的。
文件映射对象的映射视图维护对该对象的内部引用,并且文件映射对象在释放对对象的所有引用之前不会关闭。 因此,若要完全关闭文件映射对象,应用程序必须通过调用 UnmapViewOfFile 来取消映射文件映射对象的所有映射视图,并通过调用 CloseHandle关闭文件映射对象句柄。 可以按任意顺序调用这些函数。
通过映射视图修改文件时,可能不会自动更新上次修改时间戳。 如果需要,调用方应使用 SetFileTime 来设置时间戳。
从会话零以外的会话创建全局命名空间中的文件映射对象需要 SeCreateGlobalPrivilege 特权。 请注意,此特权检查仅限于创建文件映射对象,不适用于打开现有对象。 例如,如果服务或系统在全局命名空间中创建文件映射对象,则任何会话中运行的任何进程都可以访问该文件映射对象,前提是调用方具有所需的访问权限。
Windows XP:上一段中介绍的要求是 Windows Server 2003 和 Windows XP sp2 引入的
使用结构化异常处理来保护写入文件视图或从文件视图中读取的任何代码。 有关详细信息,请参阅 从文件视图读取和写入。
若要具有可执行权限的映射,应用程序必须使用 PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_READ调用 CreateFileMapping,然后使用 FILE_MAP_EXECUTE | FILE_MAP_WRITE
或 FILE_MAP_EXECUTE | FILE_MAP_READ
调用 MapViewOfFile。
在 Windows Server 2012 中,以下技术支持此函数。
科技 | 支持 |
---|---|
服务器消息块 (SMB) 3.0 协议 | 是的 |
SMB 3.0 透明故障转移 (TFO) | 是的 |
具有横向扩展文件共享的 SMB 3.0 (SO) | 是的 |
群集共享卷文件系统 (CsvFS) | 是的 |
可复原文件系统 (ReFS) | 是的 |
例子
有关示例,请参阅 创建命名共享内存 或 使用大型页面创建文件映射。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [仅限桌面应用] |
支持的最低服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | 窗户 |
标头 | memoryapi.h (包括 Windows.h、Memoryapi.h) |
库 | onecore.lib |
DLL | Kernel32.dll |
另请参阅
文件映射函数