CreateFileMapping函数

版权声明:本文为博主原创文章,欢迎转载(请声明出处),私信通知即可 https://blog.csdn.net/xinqingwuji/article/details/89029995

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

要为物理内存指定NUMA节点,请参阅CreateFileMappingNuma。

语法

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 [in]
从中创建文件映射对象的文件句柄。

必须使用与flProtect参数指定的保护标志兼容的访问权限打开该文件。它不是必需的,但建议打开要映射的文件以进行独占访问。有关更多信息,请参阅文件安全性和访问权限。

如果hFile为INVALID_HANDLE_VALUE,则调用进程还必须在dwMaximumSizeHigh和dwMaximumSizeLow参数中指定文件映射对象的大小。在此方案中,CreateFileMapping创建指定大小的文件映射对象,该对象由系统页面文件而不是文件系统中的文件支持。

lpAttributes [in,optional]
指向SECURITY_ATTRIBUTES结构的指针,该结构确定子进程是否可以继承返回的句柄。 SECURITY_ATTRIBUTES结构的lpSecurityDescriptor成员为新文件映射对象指定安全描述符。

如果lpAttributes为NULL,则无法继承句柄,文件映射对象将获取默认安全描述符。文件映射对象的默认安全描述符中的访问控制列表(ACL)来自创建者的主要或模拟令牌。有关更多信息,请参阅文件映射安全性和访问权限。

flProtect [in]
指定文件映射对象的页面保护。对象的所有映射视图必须与此保护兼容。

此参数可以是以下值之一。

含义

PAGE_EXECUTE_READ

0x20


允许将视图映射为只读,写时复制或执行访问。

必须使用GENERIC_READ和GENERIC_EXECUTE访问权限创建hFile参数指定的文件句柄。Windows Server 2003和Windows XP:在带有SP1的Windows XP和带有SP1的Windows Server 2003之前,此值不可用。

PAGE_EXECUTE_READWRITE

0x40

允许将视图映射为只读,写时复制,读/写或执行访问。

必须使用GENERIC_READ,GENERIC_WRITE和GENERIC_EXECUTE访问权限创建hFile参数指定的文件句柄。

Windows Server 2003和Windows XP:在带有SP1的Windows XP和带有SP1的Windows Server 2003之前,此值不可用。

PAGE_EXECUTE_WRITECOPY

0x80

允许将视图映射为只读,写时复制或执行访问。该值等于PAGE_EXECUTE_READ。

必须使用GENERIC_READ和GENERIC_EXECUTE访问权限创建hFile参数指定的文件句柄。

Windows Vista:在Windows Vista SP1之前,此值不可用。
Windows Server 2003和Windows XP:不支持此值。

PAGE_READONLY

0x02

允许映射视图以进行只读或写时复制访问。尝试写入特定区域会导致访问冲突。

必须使用GENERIC_READ访问权限创建hFile参数指定的文件句柄。

PAGE_READWRITE

0x04

允许映射视图以进行只读,写时复制或读/写访问。

必须使用GENERIC_READ和GENERIC_WRITE访问权限创建hFile参数指定的文件句柄。

PAGE_WRITECOPY

0x08

允许映射视图以进行只读或写时复制访问。该值相当于PAGE_READONLY。

必须使用GENERIC_READ访问权限创建hFile参数指定的文件句柄。

应用程序可以通过将它们与前面的页面保护值之一组合来为文件映射对象指定以下一个或多个属性。

Value Meaning

SEC_COMMIT

0x8000000

如果文件映射对象由操作系统页面文件(hfile参数为INVALID_HANDLE_VALUE)支持,则指定当文件视图映射到进程地址空间时,将提交整个页面范围而不是保留。系统必须具有足够的可提交页面来保存整个映射。否则,CreateFileMapping失败。

此属性对可执行映像文件或数据文件支持的文件映射对象没有影响(hfile参数是文件的句柄)。

SEC_COMMIT不能与SEC_RESERVE结合使用。

如果未指定任何属性,则假定为SEC_COMMIT。

SEC_IMAGE

0x1000000

指定hFile参数指定的文件是可执行映像文件。

SEC_IMAGE属性必须与页面保护值(如PAGE_READONLY)结合使用。但是,此页面保护值对可执行映像文件的视图没有影响。可执行文件视图的页面保护由可执行文件本身决定。

SEC_IMAGE没有其他属性有效。

SEC_IMAGE_NO_EXECUTE

0x11000000

指定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之前不支持此值。

SEC_LARGE_PAGES

0x80000000

允许大页面用于由操作系统页面文件支持的文件映射对象(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

0x10000000


将所有页面设置为不可缓存。

应用程序不应使用此属性,除非设备明确要求。使用带有SEC_NOCACHE映射的内存的互锁函数可能会导致EXCEPTION_ILLEGAL_INSTRUCTION异常。

SEC_NOCACHE要求设置SEC_RESERVE或SEC_COMMIT属性。

SEC_RESERVE

0x4000000

如果文件映射对象由操作系统页面文件(hfile参数为INVALID_HANDLE_VALUE)支持,则指定当文件视图映射到进程地址空间时,整个页面范围保留供进程以后使用而非承诺。

可以在后续调用VirtualAlloc函数时提交保留页面。提交页面后,无法使用VirtualFree函数释放或取消它们。

此属性对可执行映像文件或数据文件支持的文件映射对象没有影响(hfile参数是文件的句柄)。

SEC_RESERVE不能与SEC_COMMIT结合使用。

SEC_WRITECOMBINE

0x40000000

将所有页面设置为写入组合。

应用程序不应使用此属性,除非设备明确要求。使用带有SEC_WRITECOMBINE映射的内存的互锁函数可能会导致EXCEPTION_ILLEGAL_INSTRUCTION异常。

SEC_WRITECOMBINE需要设置SEC_RESERVE或SEC_COMMIT属性。

Windows Server 2003和Windows XP:Windows Vista之前不支持此标志。

dwMaximumSizeHigh [in]
文件映射对象最大大小的高阶DWORD。

dwMaximumSizeLow [in]
文件映射对象的最大大小的低位DWORD。

如果此参数和dwMaximumSizeHigh为0(零),则文件映射对象的最大大小等于hFile标识的文件的当前大小。

尝试映射长度为0(零)的文件失败,错误代码为ERROR_FILE_INVALID。应用程序应测试长度为0(零)的文件并拒绝这些文件。

lpName [in,optional]
文件映射对象的名称。

如果此参数与现有映射对象的名称匹配,则该函数请求具有flProtect指定的保护的对象的访问权限。

如果此参数为NULL,则创建没有名称的文件映射对象。

如果lpName与现有事件,信号量,互斥锁,等待计时器或作业对象的名称匹配,则该函数将失败,并且GetLastError函数将返回ERROR_INVALID_HANDLE。这是因为这些对象共享相同的命名空间。

该名称可以具有“Global”或“Local”前缀,以在全局或会话命名空间中显式创建对象。名称的其余部分可以包含除反斜杠字符(\)之外的任何字符。从会话零以外的会话在全局命名空间中创建文件映射对象需要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调用MapViewOfFile。 FILE_MAP_WRITE或FILE_MAP_EXECUTE | FILE_MAP_READ。

猜你喜欢

转载自blog.csdn.net/xinqingwuji/article/details/89029995