进程间通信——文件映射与句柄继承

进程间通信有多种方法,其中常用的一种便是文件映射。

往往在不同项目中对文件映射的使用策略也不一样,这里拿一种常遇到的情况来说明需要注意的。例如:A进程(system权限)含有网络模块,负责与服务器通信,而B进程(任意用户)负责实时收集数据,由于B进程处于任意用户,不能确保它是否能与服务器通信,当不能时便要将数据给A进程处理。(条件苛刻,只能用文件映射时。)


需要注意的问题:1、高权限下创建的文件映射低权限如何打开。

                                2、进程间如何同步。


对于问题一,在将文件映像到内存时,CreateFileMapping中需要设置第二个参数——SECURITY_ATTRIBUTES。创建代码:


SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;                                          //该结构不能直接修改,只能通过调用API函数来修改


InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); //初始安全描述符
SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);                  //设置DACL


sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;                                       //允许句柄继承
sa.lpSecurityDescriptor = &sa;


hMap = CreateFileMapping(, &sa,...);          //这样就创建了一个任意用户能打开的Map

对于第二个问题,进程间同步,A进程创建链接、关闭、发送、接收等事件对象(还会有很多),将句柄索引保存在文件映射内,并创建B进程继承句柄,创建时同样需要设置它们的SECURITY_ATTRIBUTES,给B进程提供一个虚拟网络类,当B进程需要链接服务器,便通过事件告诉A进程进行链接,其他同理。
例如A进程:


typedef struct _MAP_DATA_
{
      HANLDE hCenctEvent;
      HANDLE hCmpletEvent;
     ......
}MAP_DATA,*PMAP_DATA;


hAddress = (PMAP_DATA)MapViewOfFile(hMap, ....);


void InitMapAndEvent() {
    memset(hAddress , 0, sizeof(MAP_DATA));
   SECURITY_ATTRIBUTES sa;
   SECURITY_DESCRIPTOR sd;                                          


   InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
   SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);                  


   sa.nLength = sizeof(sa);
   sa.bInheritHandle = TRUE;                                      
   sa.lpSecurityDescriptor = &sa;
   hAddress ->hCenctEvent = CreateEvent(&sa, false, false, NULL);
   hAddress ->hCmpletEvent= CreateEvent(&sa, false, false, NULL);
}
DWORD WINAPI RelConect::ConectThread(LPVOID lpParam)
{
     
     RelConect *lp = (RelConect*)(lpParam);
     if(lp == NULL) while(lp->state){ 
        WaitForSingleObject(lp->hAddress ->hCenctEvent, INFINITE); //等待链接 
        //处理真实链接 
        SetEvent(lp->hAddress ->hCmpletEvent); //通知成功
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值