内存映射文件

使用内存映射文件
1.内存映射文件函数
内存映射文件包括:CreateFileMapping,OpenFileMapping,MapViewOfFile,UnmapViewOfFile和FlushViewOfFile.
创建一个内存映射文件对象使用CreateFileMapping这个步骤内存映射文件的用途(是在磁盘上建立内存映射文件,还是在页文件中建立进程间共享的映射

invoke CreateFileMapping,hFile,lpFileMappingAttributes,flProtect,dwMaximumSizeHigh,dwMaximumSizeLow,lpName
.if eax
mov hFileMap,eax

hFile:指定一个文件句柄.如果句柄是属于一个已经打开的文件的,那么内存映射文件将在这个文件上面建立;如果要建立存在于页文件中的内存映射供不同进程共享,那个hFile指定为-1
lpFileMappingAttributes:指向一个SECURITY_ATTRIBUTES结构,用来定义内存映射文件对象是否可继承
SECURITY_ATTRIBUTES结构,该结构定义如下

SECURITY_ATTRIBUTES STRUCT
nLength DWORD ? ;本结构的长度
lpSectrityDescriptor DWORD ?
bInheritHandle DWORD ? ;是否允许继承
SECURITY_ATTRIBUTES ENDS

将nLength设置为结构的长度,将bInheritHandle设置为TRUE就可以使句柄能够被子进程继承
不继承可把这个参数设置为NULL
flProtect:指定内存映射文件的保护类型,有3个取值
PAGE_READONLY:内存映射文件提交的内存页面是只读的,对应的CreateFile也要设置GENERIC_READ标志
PAGE_READWRITE:内存页面可读写,对应CreateFile设置GENERIC_READ和GENERIC_WRITE
PAGE_WRITECOPY:内存页可以有Copy on Write属性.对应CreateFile设置GENERIC_READ和GENERIC_WRITE
dwMaximumSizeHigh和dwMaximumSizeLow:这两个参数组合指定了一个64位的内存映射文件长度,如果内存映射文件用于磁盘文件的时候,这个长度如大于磁盘文件长度,磁盘文件将扩展到这个长度.如小于磁盘文件长度,那么只能存取磁盘文件的一部分,一种简单的方法是全设置成0,系统当自动调整磁盘文件大小
lpName:用来给定内存映射文件的名字.当内存映射文件作用于磁盘文件的时候,不需要给它起名;如用于进程间共享内存,那就必须为该对象命名,因为在其它进程中只有使用这个名称才能打开这个内存映射文件对象,该名字字符串不能和其他进程已创建的对象同名.

当一个进程创建内存共享文件用于和其他进程共享的时候,其它进程不能再使用CreateFileMapping去创建同样的内存映射文件对象,而是要用OpenFileMapping函数打开创建好的对象

invoke OpenFileMapping,dwDesiredAccess,bInheritHandle,lpName
.if eax
mov hFileMap,eax
.endif

dwDesiredAccess:参数指定保护类型,有3个取值
FILE_MAP_WRITE(或FILE_MAP_ALL_ACCESS):可写属性
FILE_MAP_READ:可读属性
FILE_MAP_COPY:Copy on write属性
lpName:指向的名字就是创建对象时使用的名字
如果CreateFileMapping或OpenFileMapping函数执行成功返回内存映射文件句柄,如果执行失败返回NULL

MapViewOfFile函数用来映射内存映射文件的一个视图,这个函数的用法

invoke MapViewOfFile,hFile,hFileMap,dwDesiredAccess,dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfBytesToMap
.if eax
mov lpMemory,eax
.endif

hFileMap:CreateFileMapping或OpenFileMapping返回的句柄
dwDesiredAccess:指定保护类型
FILE_MAP_WRITE(或FILE_MAP_ALL_ACCESS):可写属性
FILE_MAP_READ:可读属性
FILE_MAP_COPY:Copy on write属性
dwFileOffsetHigh和dwFileOffsetLow:组成64位的偏移量,用来指定视图的基地址是从文件的哪个位置开始映射
dwNumberOfBytesToMap:指定映射的字节数,如果设置为0则映射的是整个文件,同时偏移地址被忽略
如果映射成功,返回一个地址,如果映射失败,则返回NULL

当不再使用映射文件后,通过UnmapViemOfFile函数撤销映射并使用CloseHandle函数关闭内存映射文件对象句柄

invoke UnmapViewOfFile,lpMemory
invoke CloseHandle,hFileMap

视图中的内存修改后,系统会在视图撤销映射或文件映射对象被删除时自动将数据写到磁盘上,但可以根据需要将对文件的修改立即写到磁盘上,该功能的函数FlushViewOfFile

invoke FlushViewOfFile,lpMemory,dwFileSize

该函数将从指定地址开始,指定大小的数据块中的脏页面写到磁盘,指定的内存范围必须位于视图的边界之内

2使用内存映射文件读写文件
内存映射文件读写文件的步骤
(1) 调用CreateFile打开想要映射的文件,得到hFile
(2) 调用CreateFileMapping函数生成一个建立在CreateFile函数创建的文件对象基础上的内存映射对象,得到hFileMap
(3) 调用MapViewOfFile把整个文件的一个区域或整个文件映射到内存中,得到指向映射到内存的第一个字节的指针lpMemory
(4) 用该指针来读写文件
(5) 调用UnmapViewOfFile来解除文件映射,传入参数为lpMemory
(6) 调用CloseHandle来关闭内存映射文件,传入参数为hFileMap
(7) 调用CloseHandle来关闭文件,传入参数为hFile
例程: …………….

3使用内存映射文件在进程间共享数据
进程间共享数据的步骤如下:
(1) 调用OpenFileMapping打开一个命名的内存映射文件对象,得到hFileMap,打开成功跳到(3),否则表示此程式是第一个副本,继续执行步骤(2)
(2) 调用CreateFileMapping函数创建一个命名的内存映射对象,得到hFileMap
(3) 调用MapViewOfFile函数映射对象的一个视图,得到lpMemory
(4) 用该指针来读写共享的内存区域.
(5) 调用UnmapViewOfFile来解锁视图映射,传入参数为lpMemory
(6) 调用CloseHandle来关闭内存映射文件,传入参数为hFileMap
例程: …………….

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注