Windows上的共享内存访问权限

时间:2008-10-06 21:45:07

标签: windows shared memory-access

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

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

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

这就是为什么我认为问题与权限有关。有人可以对此发表评论吗?

编辑:

我用来创建内存映射文件的ACL和同步访问的Mutex对象如下:

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)"); 

我认为这可能是问题的一部分。

4 个答案:

答案 0 :(得分:9)

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

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

此问题的快速解决方法是使用全局命名空间,方法是将“Global \”添加到我使用的每个内核对象名称并完成操作。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

您是否尝试将文件移至其他位置。尝试将其放在“共享文档”文件夹中,这似乎是Vista中最易于访问的文件夹。