进程间通信之利用CreateFilemapping()

这两天在复习进程间通信,复习一下记不住,复习一下记不住。。。就写个小博客献个丑,先来第一个内存映射

代码亲测通过

CreateFileMapping()的最后的一位用来做进程间通信

步骤:

1.CreateFileMapping()创建一个内存映射对象
2.利用MapViewOfFile()将文件映射到进程地址空间
3.UnmapViewOfFile()解除映射

Server端

#include "stdafx.h"
#include <windows.h>

int main()
{

HANDLE MappingHandle = NULL;
PVOID BaseAddress = NULL;
MappingHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE/*物理页*/, 0/*高位*/,0x1000/*低位*/, L"HelloWorld");

if (MappingHandle==NULL)
{
return 0;
}

BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);//基地址查找


__try
{
memcpy(BaseAddress, "HelloClient", strlen("HelloClient")+1);

printf("Input AnyKey To Continue\r\n");
getchar();

printf("%s\r\n", BaseAddress);
}
__except (EXCEPTION_EXECUTE_HANDLER)//例外执行
{
printf("异常\r\n");
goto Exit;
}

 


Exit:
if (MappingHandle!=NULL)
{
CloseHandle(MappingHandle);
MappingHandle = NULL;
UnmapViewOfFile(BaseAddress);

}

printf("Input AnyKey To Exit\r\n");
getchar();
return 0;
}

 

Client端 

#include "stdafx.h"
#include <windows.h>

int main()
{

HANDLE MappingHandle = NULL;
PVOID BaseAddress = NULL;
//此下几行代码为主要点
MappingHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"HelloWorld");
if (MappingHandle == NULL)
{
return 0;
}
BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);

__try
{
memcpy(BaseAddress, "HelloServer", strlen("HelloWorld") + 1);
printf("%s\r\n", BaseAddress);

}
__except (EXCEPTION_EXECUTE_HANDLER)
{
goto Exit;
}

Exit:

if (MappingHandle != NULL)
{
CloseHandle(MappingHandle);
MappingHandle = NULL;
UnmapViewOfFile(BaseAddress);

}
printf("Input AnyKey To Exit\r\n");
getchar();
return 0;
}

函数解释:

CreateFileMapping():

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

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:在Windows XP SP2和Windows Server 2003 SP1之前,此值不可用。
 
PAGE_EXECUTE_READWRITE
0x40允许将视图映射为只读,写时复制,读/写或执行访问。

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

Windows Server 2003和Windows XP:在Windows XP SP2和Windows Server 2003 SP1之前,此值不可用。
 
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参数指定的文件句柄。
 


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

价值意义
SEC_COMMIT
0x8000000如果文件映射对象由操作系统分页文件(hfile参数为INVALID_HANDLE_VALUE)支持,则指定当文件的视图映射到进程地址空间时,提交整个页面范围而不是保留。系统必须有足够的提交页面来保存整个映射。否则,CreateFileMapping将失败。
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 [,可选]
文件映射对象的名称。

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

如果此参数为NULL,则创建文件映射对象而不使用名称。

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

该名称可以具有“全局”或“本地”前缀,以在全局或会话命名空间中显式创建对象。名称的其余部分可以包含除反斜杠字符(\)之外的任何字符

 

MapViewOfFile():

将文件映射的视图映射到调用进程的地址空间。
要为视图指定建议的基址,请使用MapViewOfFileEx函数。但是,不推荐这种做法。
LPVOID WINAPI MapViewOfFile(
  _In_ HANDLE hFileMappingObject,
  _In_ DWORD dwDesiredAccess,
  _In_ DWORD dwFileOffsetHigh,
  _In_ DWORD dwFileOffsetLow,
  _In_ SIZE_T dwNumberOfBytesToMap
);
Return value
If the function succeeds, the return value is the starting address of the mapped view.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
参数
hFileMappingObject [in]
文件映射对象的句柄。 CreateFileMapping和OpenFileMapping函数返回此句柄。
dwDesiredAccess [in]
访问文件映射对象的类型,确定页面的保护。此参数可以是以下值之一。
价值意义
FILE_MAP_ALL_ACCESS映射文件的读/写视图。文件映射对象必须使用PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护创建。

当与MapViewOfFile函数一起使用时,FILE_MAP_ALL_ACCESS等同于FILE_MAP_WRITE。
 
FILE_MAP_COPY映射文件的写时复制视图。文件映射对象必须使用PAGE_READONLY,PAGE_READ_EXECUTE,PAGE_WRITECOPY,PAGE_EXECUTE_WRITECOPY,PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护创建。

当进程写入写时复制页面时,系统将原始页面复制到进程私有的新页面。新页面由页面文件支持。新页面的保护从写时复制变为读/写。

当指定写时复制访问时,系统和进程提交的费用用于整个视图,因为调用进程可以潜在地写入视图中的每个页面,使所有页面都是私有的。新页面的内容永远不会写回原始文件,并且在视图未映射时丢失。
 
FILE_MAP_READ映射文件的只读视图。尝试写入文件视图会导致访问冲突。

必须使用PAGE_READONLY,PAGE_READWRITE,PAGE_EXECUTE_READ或PAGE_EXECUTE_READWRITE保护创建文件映射对象。
 
FILE_MAP_WRITE映射文件的读/写视图。文件映射对象必须使用PAGE_READWRITE或PAGE_EXECUTE_READWRITE保护创建。

当与MapViewOfFile一起使用时,(FILE_MAP_WRITE | FILE_MAP_READ)和FILE_MAP_ALL_ACCESS等效于FILE_MAP_WRITE。

上述值中的每一个可以与以下值组合。
价值意义
FILE_MAP_EXECUTE映射文件的可执行视图(映射内存可以作为代码运行)。文件映射对象必须使用PAGE_EXECUTE_READ,PAGE_EXECUTE_WRITECOPY或PAGE_EXECUTE_READWRITE保护创建。
Windows Server 2003和Windows XP:此值可从Windows XP SP2和Windows Server 2003 SP1启动。
对于使用SEC_IMAGE属性创建的文件映射对象,dwDesiredAccess参数不起作用,应设置为任何有效值,如FILE_MAP_READ。
dwFileOffsetHigh [in]
视图开始的文件偏移量的高阶DWORD。

dwFileOffsetLow [in]
视图要开始的文件偏移量的低阶DWORD。高和低偏移量的组合必须在文件映射内指定偏移量。它们还必须匹配系统的内存分配粒度。也就是说,偏移量必须是分配粒度的倍数。要获取系统的内存分配粒度,请使用GetSystemInfo函数,该函数填充SYSTEM_INFO结构的成员。

dwNumberOfBytesToMap [in]
要映射到视图的文件映射的字节数。所有字节必须在CreateFileMapping指定的最大大小之内。如果此参数为0(零),映射将从指定的偏移扩展到文件映射的结尾。

posted @ 2018-01-30 18:33  _Flame  阅读(880)  评论(0编辑  收藏  举报