Windows上的共享内存访问权限

问题描述:

我开发了一个使用共享内存---即内存映射文件进行进程间通信的Windows应用程序。我有一个Windows服务,它执行一些处理并定期将数据写入内存映射文件。我有一个单独的Windows应用程序,从内存映射文件读取并显示信息。该应用程序在Windows XP,XP Pro和Server 2003上按预期工作,但不在Vista上。Windows上的共享内存访问权限

我可以看到正在写入内存映射文件的数据正在由Windows服务正确发生,因为我可以用文本编辑器打开文件并查看存储的消息,但“使用者”应用程序无法读取从文件中。这里需要注意的一件有趣事情是,如果关闭消费者应用程序并重新启动它,它将消耗之前写入内存映射文件的消息。

此外,另一个奇怪的是,当我使用远程桌面连接到Windows主机并通过远程桌面调用/使用使用者应用程序时,我会得到相同的行为。但是,如果我调用远程桌面并使用以下命令连接到目标主机的控制台会话:mstsc -v:servername /F -console,则一切正常。

所以这就是为什么我认为问题与权限有关。任何人都可以评论这个吗?

编辑:

,我使用创建的内存映射文件和sychronize访问如下互斥对象的ACL:

TCHAR * szSD = TEXT("D:") 
       TEXT("(A;;RPWPCCDCLCSWRCWDWOGAFA;;;S-1-1-0)") 
       TEXT("(A;;GA;;;BG)") 
       TEXT("(A;;GA;;;AN)") 
       TEXT("(A;;GA;;;AU)") 
       TEXT("(A;;GA;;;LS)") 
       TEXT("(A;;GA;;;RD)") 
       TEXT("(A;;GA;;;WD)") 
       TEXT("(A;;GA;;;BA)"); 

我觉得这可能是问题的一部分。

您是否试过将文件移动到其他位置。尝试将它放在'共享文档'文件夹中,这似乎是Vista中最容易访问的文件夹。

+0

共享文档是IPC相关文件的高度不安全位置 - 不要这样做。 – 2008-10-06 22:15:57

你打开共享内存部分的访问权限是什么?尝试与FILE_MAP_ALL_ACCESS并努力工作。还要确保生产者和消费者之间没有竞争条件 - 哪一个创建共享内存?确保在另一个人尝试打开它之前创建了它。一种方法是在启动子进程之前在父进程中创建该部分 - 如果您正在使用父/子体系结构。

您的孩子可能需要在Vista上运行提升才能被允许访问共享内存。它也可能与您正在使用的窗口会话有关。服务在会话0中运行(我认为),而其他应用程序(特别是通过远程桌面登录时)可能会在另一个会话中运行。

+0

所以我使用FILE_MAP_ALL_ACCESS来映射共享内存,并且我设计了代码,以便谁先创建共享内存并不重要。但你对这次会议的建议很有意思。我会研究这个。 – 2008-10-06 23:45:27

所以我找到了解决我的问题:

在Windows XP中,所有命名的内核对象,如互斥,信号量和内存映射的对象存储在同一个命名空间。因此,当不同用户会话中的不同进程使用其名称引用特定对象时,它们将获得该对象的句柄。但是,作为安全防范措施,Windows终端服务为从其会话中启动的进程引用的内核对象创建单独的名称空间。 Windows Vista也内置了这种行为,所以这就是为什么我的应用在Vista上无法正常工作。详细来说,我有一个在空会话中运行的Windows服务和一个在用户会话中运行的应用程序,所以我的命名对象是在不同的命名空间中创建的。

这个问题的快速解决方案是使用全局命名空间,通过预先将“Global \”添加到我使用的每个内核对象名称,并且做了诀窍。

+0

您可能在您的系统上创建了安全漏洞。 – 2008-11-11 22:09:53

+1

那么对这个问题有不同的看法。有时候你想给服务更高的权限和能力(比如本地系统),而不是需要能够与该服务接口的用户应用程序。可争辩的是,您只需提供服务而不是应用程序的所有访问权限即可启用安全性。但是,您可以查看服务是否存在潜在的安全漏洞。但我不同意。 – Dan 2009-07-24 21:41:13

前缀“Global \”可能无法在共享内存上工作。请参阅"Impact of Session 0 Isolation on Services and Drivers in Windows Vista"解决方案。