CreateFileMappingA 函数 (winbase.h)
为指定文件创建或打开命名或未命名的文件映射对象。
若要指定物理内存的 NUMA 节点,请参阅 CreateFileMappingNuma。
语法
HANDLE CreateFileMappingA(
[in] HANDLE hFile,
[in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
[in] DWORD flProtect,
[in] DWORD dwMaximumSizeHigh,
[in] DWORD dwMaximumSizeLow,
[in, optional] LPCSTR lpName
);
参数
[in] hFile
要从中创建文件映射对象的文件的句柄。
必须使用与 flProtect 参数指定的保护标志兼容的访问权限打开文件。 这不是必需的,但建议打开要映射的文件进行独占访问。 有关详细信息,请参阅 文件安全性和访问权限。
如果 hFile是INVALID_HANDLE_VALUE,则调用进程还必须在 dwMaximumSizeHigh 和 dwMaximumSizeLow 参数中指定文件映射对象的大小。 在此方案中, CreateFileMapping 会创建一个指定大小的文件映射对象,该对象由系统分页文件而不是文件系统中的文件提供支持。
[in, optional] lpFileMappingAttributes
指向 SECURITY_ATTRIBUTES 结构的指针,该结构确定是否可由子进程继承返回的句柄。 SECURITY_ATTRIBUTES 结构的 lpSecurityDescriptor 成员为新的文件映射对象指定安全描述符。
如果 lpFileMappingAttributes 为 NULL,则无法继承句柄,并且文件映射对象将获取默认的安全描述符。 访问控制列出了来自创建者的主要令牌或模拟令牌的文件映射对象的默认安全描述符中 (ACL) 。 有关详细信息,请参阅 文件映射安全性和访问权限。
[in] flProtect
指定文件映射对象的页保护。 对象的所有映射视图都必须与此保护兼容。
此参数的取值可为下列值之一:
应用程序可以通过将以下一个或多个属性与前面的页面保护值组合来为文件映射对象指定以下一个或多个属性。
值 | 含义 |
---|---|
|
如果文件映射对象由操作系统分页文件提供支持, (hfile 参数 INVALID_HANDLE_VALUE) ,则指定在将文件的视图映射到进程地址空间时,将提交而不是保留整个页面范围。 系统必须有足够的可提交页面来保存整个映射。 否则, CreateFileMapping 将失败。
对于由可执行图像文件或数据文件支持的文件映射对象, (hfile 参数是文件) 句柄,则此属性不起作用。 SEC_COMMIT 不能与 SEC_RESERVE结合使用。 如果未指定任何属性,则假定 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 才支持此值。 Windowsxp: 不支持此值。 |
|
将所有页面设置为不可缓存。
应用程序不应使用此属性,除非设备显式需要。 将互锁 函数与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。 发生这种情况是因为这些对象共享相同的命名空间。
名称可以具有“Global”或“Local”前缀,以在全局命名空间或会话命名空间中显式创建对象。 名称的其余部分可以包含除反斜杠字符 (\) 以外的任何字符。 从会话 0 以外的会话在全局命名空间中创建文件映射对象需要 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 设置时间戳。
从会话 0 以外的会话在全局命名空间中创建文件映射对象需要 SeCreateGlobalPrivilege 特权。 请注意,此特权检查仅限于创建文件映射对象,不适用于打开现有对象。 例如,如果服务或系统在全局命名空间中创建文件映射对象,则在任何会话中运行的任何进程都可以访问该文件映射对象,前提是调用方具有所需的访问权限。
Windowsxp: 上一段中所述的要求是在 Windows Server 2003 和 Windows XP SP2 中引入的
使用结构化异常处理来保护写入文件视图或从文件视图中读取的任何代码。 有关详细信息,请参阅 从文件视图中读取和写入。
若要具有具有可执行权限的映射,应用程序必须使用 PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_READ 调用 CreateFileMapping,然后使用 或 FILE_MAP_EXECUTE | FILE_MAP_READ
调用 MapViewOfFileFILE_MAP_EXECUTE | FILE_MAP_WRITE
。
在 Windows Server 2012 中,以下技术支持此函数。
技术 | 支持 |
---|---|
服务器消息块 (SMB) 3.0 协议 | 是 |
SMB 3.0 透明故障转移 (TFO) | 是 |
具有横向扩展文件共享的 SMB 3.0 (SO) | 是 |
群集共享卷文件系统 (CSV) | 是 |
弹性文件系统 (ReFS) | 是 |
示例
有关示例,请参阅 创建命名共享内存 或使用 大型页面创建文件映射。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | winbase.h (包括 Windows.h、Memoryapi.h) |
Library | Kernel32.lib |
DLL | Kernel32.dll |
另请参阅
文件映射函数