小甲鱼 发表于 2016-3-28 16:57:08

CreateFileMapping

注:本文档由 Diu 翻译,小甲鱼校对。

函数功能:

创建或打开指定文件的命名或未命名的文件映射对象。

指定物理内存 NUMA 节点,请参见 CreateFileMappingNuma。


API 函数原型:

注释:_In_ 说明该参数是输入的,_In_opt_ 说明参数是输入的,同时是可选的。
HANDLE WINAPI CreateFileMapping(
_In_   HANDLE                hFile,
_In_opt_ LPSECURITY_ATTRIBUTES lpAttributes,
_In_   DWORD               flProtect,
_In_   DWORD               dwMaximumSizeHigh,
_In_   DWORD               dwMaximumSizeLow,
_In_opt_ LPCTSTR               lpName
);

参数解析:


参数 含义
hFile 1. 指定被用来创建文件映射对象的文件句柄
2. 文件必须以与 flProtect 参数指定的保护标志相兼容的访问权限打开。建议将被映射的文件以互斥访问模式打开,虽然这并不是必须的。更多内容,请参考 File Security and Access Right
3. 如果 hFile 是 INVALID_HANDLE_VALUE,调用进程必须在 dwMaximumSizeHigh 和 dwMaximumSizeLow 参数中指定文件映射对象的大小。在这种情况下,通过 CreatFileMapping 创建一个指定大小的映射文件对象,并且是由系统分页文件所支持的,而不是通过文件系统中的一个文件
lpAttributes 1. 指向 SECURITY_ATTRIBUTES 结构的指针,并且该结构指明返回的句柄是否可以被子进程所继承,SECURITY_ATTRIBUTES 结构的 lpSecurityDescriptor 成员指定一个新文件映射对象的安全描述符
2. 如果 lpAttributes 参数的值为 NULL,表示句柄不能够被继承,并且文件映射对象有一个默认的安全描述符。在文件映射对象的默认安全描述符中的访问控制列表(ACL)来自创建者的主要或模拟令牌。更多信息,请参见 File Security and Access Right
flProtect 1. 指定文件映射对象的页面保护。对象的所有映射视图必须与此保护兼容

2. 此参数可以是下列值中的某一个:

值 含义
PAGE_EXECUTE_READ
(0x20) 1. 允许视图被映射为只读、写时复制或执行访问
2. 由 hFile 参数指定的文件句柄必须以 GENERIC_READ 和 GENERIC_EXECUTE 访问权限创建
3. Windows Server 2003 和 Windows XP:Windows XP SP2 和 Windows Server 2003 SP1 之前此值不可用
PAGE_EXECUTE_READWRITE
(0x40) 1. 允许视图被映射为只读、写时复制,读/写或者执行访问
2. 由 hFile 参数指定的文件句柄必须以 GENERIC_READ,GENERIC_WRITE 和 GENERIC_EXECUTE 访问权限创建
3. Windows Server 2003 和 Windows XP:Windows XP SP2 和 Windows Server 2003 SP1 之前此值不可用
PAGE_EXECUTE_WRITECOPY
(0x80) 1. 允许视图被映射为只读、写时复制或执行访问。这个数值等同于PAGE_EXECUTE_READ
2. 由 hFile 参数指定的文件句柄必须以 GENERIC_READ 和 GENERIC_EXECUTE访 问权限创建
3. Windows Vista:Windows Vista SP1 之前不支持此值
4. Windows Server 2003 和 Windows XP:不支持此值
PAGE_READONLY
(0x02) 1. 允许视图被映射为只读或写时复制访问。尝试写入特定区域会导致非法访问异常
2. 由 hFile 参数指定的文件句柄必须以 GENERIC_READ 访问权限创建

PAGE_READWRITE
(0x04) 1. 允许视图被映射为只读,写时复制或读/写访问
2. 由 hFile 参数指定的文件句柄必须以 GENERIC_READ 和 GENERIC_WRITE 访问权限创建
PAGE_WRITECOPY
(0x08) 1. 允许视图被映射为只读、写时复制访问。这个数值等同于 PAGE_READONLY
2. 由 hFile 参数指定的文件句柄必须以 GENERIC_READ 访问权限创建

3. 应用程序可以为文件映射对象指定一个或多个下列属性,并将它们与前面的一个页面保护值相结合:

值 含义
SEC_COMMIT
(0x8000000) 1. 如果文件映射对象是被操作系统的页文件所支持的(hFile 参数是 INVALID_HANDLE_VALUE),表明当一个文件的视图被映射到进程的地址空间时,页的整个范围将被提交而非保留。系统必须有足够的可提交页面来保存整个映射。否则,CreatFileMapping 调用失败
2. 此属性不影响可执行映像文件或数据文件支持的文件映射对象
3. SEC_COMMIT 不能与 SEC_RESERVE 同时使用
4. 如果没有指定属性,那么默认会假定为 SEC_COMMIT
SEC_IMAGE
(0x1000000) 1. 指定的 hFile 参数指定的文件是可执行映像文件
2. 该 SEC_IMAGE 属性必须与页面保护值,如 PAGE_READONLY 组合。然而,此页面保护值不影响可执行映像文件的视图。可执行映像文件的视图的页面保护是由可执行文件本身决定的
3. 和 SEC_IMAGE 属性一同使用的属性都无效
SEC_IMAGE_NO_EXECUTE
(0x11000000) 1. 指定的 hFile 参数指定的文件是不会执行的可执行映像文件并且加载的图像文件没有进行强制完整性检查。此外,映射一个以 SEC_IMAGE_NO_EXECUTE 属性创建的文件映射对象不会使用 PsSetLoadImageNotifyRoutine 内核 API 注册驱动程序回调函数
2. SEC_IMAGE_NO_EXECUTE 属性必须结合 PAGE_READONLY 页面保护值。和 SEC_IMAGE_NO_EXECUTE 一同使用的其他属性都是无效的
3. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, 和 Windows XP:在Windows Server 2012 和 Windows 8 以前不支持此值
SEC_LARGE_PAGES
(0x80000000) 1. 被操作系统页文件所支持的文件映射对象所使用的大页面被允许(hFile 参数是INVALID_HANDLE_VALUE)。这个属性不支持由可执行镜像文件或数据文件所支持的文件映射对象(hFile 参数是一个可执行镜像文件或数据文件的句柄)
2. 文件映射对象的最大大小必须是 GetLargePageMinimum 函数返回的一个较大的页面最小大小的倍数。如果不是,那么 CreateFileMapping 调用失败。当映射一个以 SEC_LARGE_PAGES 创建的文件映射对象的视图时,基地址和视图的大小必须是最小的大页面大小的倍数
3. SEC_LARGE_PAGES 要求 SeLockMemoryPrivilege 特权被调用者启用
4. 如果指定了 SEC_LARGE_PAGES,也必须指定 SEC_COMMIT
5. Windows Server 2003:Windows Server 2003 SP1 之前不支持此值
6. Windows XP:不支持此值
SEC_NOCACHE
(0x10000000) 1. 设置所有页面不能被缓存
2. 应用程序不应使用此属性,除非设备的明确要求。对以 SEC_NOCACHE 映射的内存使用互锁函数会导致 EXCEPTION_ILLEGAL_INSTRUCTION 异常
3. SEC_NOCACHE 需要设置 SEC_RESERVE 或 SEC_COMMIT 属性
SEC_RESERVE
(0x4000000) 1. 如果文件映射对象是被操作系统的页文件所支持的(hFile 参数是 INVALID_HANDLE_VALUE),表明当一个文件的视图被映射到进程的地址空间时,页的整个范围将被保留用作以后的使用而不是提交
2. 保留页可以在随后的 VirtualAlloc 函数调用中被提交。当这些页面被提交后,不能通过 VirtualFree 函数释放或者重新提交
3. SEC_COMMIT 不能与 SEC_RESERVE 结合使用
SEC_WRITECOMBINE
(0x40000000) 1. 将所有页面设置为写聚合
2. 应用程序不应使用此属性,除非设备的明确要求。对以 SEC_WRITECOMBINE 映射的内存使用互锁函数会导致 EXCEPTION_ILLEGAL_INSTRUCTION 异常
3. SEC_WRITECOMBINE 需要设置 SEC_RESERVE 或 SEC_COMMIT 属性
4. Windows Server 2003 和 Windows XP:在 Windows Vista 之前不支持此标志

dwMaximumSizeHigh 文件映射对象最大大小的高 32 位
dwMaximumSizeLow 1. 文件映射对象最大大小的低32位
2. 如这个参数和 dwMaximumSizeHigh 都是零,那么文件映射对象的最大大小等于 hFile 指定文件的实际大小
3. 映射一个大小为 0 的文件将会引发出错码为 ERROR_FILE_INVALID 的错误。应用程序应该检测大小为 0 的文件,并拒绝这些文件
lpName 1. 文件映射对象的名称
2. 如果这个参数与一个已经存在的文件映射对象的名称相同,那么该函数请求以 flProtect 指定的保护属性访问该对象
3. 如果这个参数为 NULL,那么创建的这个文件映射对象将没有名称
4. 如果 lpName 与一个现有的事件,信号量,互斥锁,可等待定时器,或工作对象同名,那么函数调用失败,并且 GetLassError 函数返回 ERROR_INVALID_HANDLE。因为这些对象共享相同的命名空间
5. 该名称可以有一个 "Global\" 或 "Local\" 前缀来在全局或会话命名空间中显示地创建对象。其余的名称可以包含除反斜杠字符(\)以外的任何字符。在全局命名空间中从一个会话而不是会话0中创建一个文件映射对象需要 SeCreateGlobalPrivilege 特权。更多信息,请参考 Kernel Object Namespaces
6. 快速用户切换是通过使用终端服务会话实现的。第一个用户以会话 0 登陆,第二个用户以会话 1 登陆等等。内核对象名称必须遵循为终端服务所列出的指导原则,以便应用程序可以支持多个用户


返回值:

1. 如果函数执行成功,返回值是新创建的文件映射对象的句柄。。

2. 如果在函数调用之前,该对象存在,函数将返回现有对象的句柄(并且是对象现有的大小而不是调用函数时指定的大小),并且 GetLastError 函数返回 ERROR_ALREADY_EXISTS

3. 如果函数失败,则返回值为 NULL

想要获取更多错误有关信息,请调用 GetLastError


备注:

1. 创建一个文件映射对象后,文件大小必须不超过该文件映射对象的大小;否则,并不是所有的文件内容都可以共享。

2. 如果一个应用程序指定一个文件映射对象的大小大于磁盘上的实际命名文件的大小,并且如果页面保护允许写入访问权限(也就是说,flProtect 参数指定了 PAGE_READWRITE 或 PAGE_EXECUTE_READWRITE),那么磁盘上的文件会增加大小到文件映射对象的大小。如果文件被扩展,文件旧的尾端和文件的新的尾端之间的文件的内容不保证为零,这个行为由文件系统来定义。如果磁盘上的文件不能够被扩展,那么 CreateFileMapping 函数调用失败,并且 GetLastError 函数返回 ERROR_DISK_FULL。

3. 操作系统分页文件支持的文件映射对象中的页的初始内容为0。

4. CreateFileMapping 函数返回的句柄对那个新的文件映射对象具有完全的访问权限,并且能够被任何需要文件映射对象句柄的函数所使用。

5. 多进程可以通过使用单个共享文件映射对象或创建单独的文件映射对象来共享同一文件的视图。一个文件映射对象能够被多个进程共享,通过在创建进程时继承句柄,复制句柄或通过名字打开一个文件映射对象。更多信息,请参考 CreateProcess, DuplicateHandle 和 OpenFileMapping 函数。

6. 创建一个文件映射对象并没有将视图映射到一个进程地址空间。MapViewOfFile 和 MapViewOfFileEx 函数才映射一个文件的视图到进程地址空间。

7. 在一个重要的例外情况下,来自同一文件的任何文件映射对象的文件视图在特定时间内是一致的或相同的。在一个进程中的视图和被不同进程映射的视图才能保证一致性。

8. 唯一的例外是与远程文件相联系。虽然 CreateFileMapping 函数能够处理远程文件,但是并不能保证他们的一致性。例如,如果两台电脑都将一个文件映射为可写的,并且同时改变相同的页面,每台电脑只看到他们自己对那个页面所做的修改。所以当数据在磁盘上更新的时候,并没有合并他们的内容。

9. 一个映射的文件和一个通过输入和输出(I/O)函数(ReadFile 和 WriteFile)访问的文件并不需要保持一致性。

10. 一个文件映射对象的映射视图维持着对象的内部引用,直到所有的引用被释放,文件映射对象才能够被关闭。因此,要想完全关闭一个文件映射对象,应用程序必须通过调用 UnmapViewOfFile 来解除文件映射对象的所有映射视图,并且通过调用 CloseHandle 来关闭文件映射对象的句柄。这些函数能够以任意的顺序被调用。

11. 当通过映射的视图修改文件时,最后的修改时间戳可能不能够自动更新。如果需要自动更新,可以使用 SetFileTime 来设置一个时间戳。

12. 在全局命名空间中从一个会话而不是会话 0 中来创建一个文件映射对象需要 SeCreateGlobalPrivilege 特权。注意这个特权被限制在创建文件映射对象的时候使用,而不能应用于打开一个已经存在的对象。例如,如果一个服务或者系统在全局命名空间中创建了一个文件映射对象,在任何会话中运行的任何进程都可以访问该文件映射对象,该对象提供了该调用方具有所需的访问权限。

13. Windows XP:在前几段中通过 Windows Server 2003 和 Windows XP 介绍了需求描述。

14. 使用结构化异常处理来保护写入或读取文件视图的任何代码。更多信息,请参见 Reading and Writing From a File View。

15. 为了有可执行权限的映射,应用程序必须调用 CreateFileMapping 函数,并且设置 PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_READ。然后调用 MapViewOfFile 函数,并且设置 FILE_MAP_EXECUTE | FILE_MAP_WRITE 或 FILE_MAP_EXECUTE | FILE_MAP_READ。

16. Windows Server 2012 中,这个功能是通过以下技术支持。


技术 支持
Server Message Block (SMB) 3.0 protocol Yes
SMB 3.0 Transparent Failover (TFO) Yes
SMB 3.0 with Scale-out File Shares (SO) Yes
Cluster Shared Volume File System (CsvFS) Yes
Resilient File System (ReFS) Yes


需求:


Minimum supported client Windows XP [仅桌面应用程序]
Minimum supported server Windows 2003 [仅桌面应用程序]
Header Winuser.h (包含于 Windows.h)
Library User32.lib
DLL User32.dll
Unicode and ANSI names AppendMenuW (Unicode) 和 AppendMenuA (ANSI)


【API档案】版权归鱼C工作室(www.fishc.com)所有,转载请注明来源。

页: [1]
查看完整版本: CreateFileMapping