Windows10系统FileMapping跨进程共享需要权限

3 篇文章 0 订阅
1 篇文章 0 订阅

通过CreateFileMapping - OpenFileMapping - MapViewOfFile跨进程共享内存映射时需要注意,在CreateFileMapping创建文件映射时需要设置权限,同时,指定映射名称时需要加"Global\"前缀。

- 第一步:创建FileMapping

  • 参数1:INVALID_HANDLE_VALUE创建的FileMapping不关联到具体文件,直接在内存创建文件映射,
  • 参数2:不能传递NULL,需要指定权限
  • 参数6:ShareName需要指定"Global\"前缀
  const int DATA_SIZE = 8294400;
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;
  InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(&sd, true, NULL, false);
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.lpSecurityDescriptor = &sd;
  sa.bInheritHandle = false;
  FString name = TEXT("Global\\") + ShareName;
  m_hShareFile = ::CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, DATA_SIZE, *name);

创建成功后通过资源监视器查看句柄
在这里插入图片描述如果不指定"Global\"前缀,则创建出来的句柄处于session范围内,不能跨进程共享
在这里插入图片描述

注意:在整个共享内存执行期间,CreateFileMapping创建的句柄不可以调用CloseHandle关闭

- 第二步:写进程调用OpenFileMapping和MapViewOfFile打开文件映射,写入数据

    XmlRequestResult r = new XmlRequestResult();

    IntPtr hFile = IntPtr.Zero;
    IntPtr hMap = IntPtr.Zero;
    int totalSize = 0;
    hFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, true, "Global\\" + uid);
    if (IntPtr.Zero == hFile)
    {
      r.Code = XmlRequestResult.ExceptionCode.invalid_param;
      r.Message = "OpenFileMapping failed";
    }
    else
    {
      IntPtr pBuff = MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, (uint)DATA_SIZE);
      if (IntPtr.Zero == pBuff)
      {
        r.Code = XmlRequestResult.ExceptionCode.invalid_param;
        r.Message = "MapViewOfFile failed";
      }
      else
      {
        //...C#调用Marshal.Copy写入数据
        UnmapViewOfFile(pBuff);
      }
      CloseHandle(hFile);
    }

写入完成后及时调用UnmapViewOfFile和CloseHandle关闭文件映射

- 第三步:读进程调用OpenFileMapping和MapViewOfFile打开文件映射,读取数据

  FString strData; //用于存储共享内存中的数据
  BYTE *pdata = NULL;// 共享内存指针                                                  
  FString name = TEXT("Global\\") + ShareName;
  HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, *name);// 先判断要打开的共享内存名称是否存在
  if (NULL == hMap)
  {
    ErrorMessage = TEXT("OpenFileMapping failed");
  }
  else
  {
    pdata = (BYTE*)::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (NULL == pdata) {
      ErrorMessage = TEXT("MapViewOfFile failed");
    }
    else {
      //...C++调用memcpy读取数据
      ::UnmapViewOfFile(pdata);
    }
    ::CloseHandle(hMap);
  }

读取完成后及时调用UnmapViewOfFile和CloseHandle关闭文件映射

如果按照以上方法创建了FileMapping句柄,调用OpenFileMapping打开句柄还是失败,那么可能是调用CreateFileMapping创建句柄的进程权限不足。
在这里插入图片描述

目前测试来看,在ASP.NET服务页面调用CreateFileMapping创建的文件映射,本进程可以打开,其他进程是无法打开的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值