Windows 上的共享内存访问权限

发布于 2024-07-07 07:55:16 字数 1028 浏览 7 评论 0原文

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

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

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

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

编辑:

我用来创建内存映射文件和同步访问的互斥对象的 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)"); 

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

I've developed a windows application that uses shared memory---that is---memory mapped files for interprocess communication. I have a windows service that does some processing and periodically writes data to the memory mapped file. I have a separate windows application that reads from the memory mapped file and displays the information. The application works as expected on Windows XP, XP Pro and Server 2003, but NOT on Vista.

I can see that the data being written to the memory mapped file is happening correctly by the windows service because I can open the file with a text editor and see the stored messages, but the "consumer" application can't read from the file. One interesting thing to note here, is that if I close the consumer application and restart it, it consumes the messages that were previously written to the memory mapped file.

Also, another strange thing is that I get the same behavior when I connect to the windows host using Remote Desktop and invoke/use the consumer application through remote desktop. However, if I invoke the Remote Desktop and connect to the target host's console session with the following command: mstsc -v:servername /F -console, everything works perfectly.

So that's why I think the problem is related to permissions. Can anyone comment on this?

EDIT:

The ACL that I'm using to create the memory mapped file and the Mutex objects that sychronize access is as follows:

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

I think this may be part of the issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

臻嫒无言 2024-07-14 07:55:16

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

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

解决此问题的快速方法是通过在我使用的每个内核对象名称前面添加“Global\”来使用全局命名空间,这就达到了目的。

So I found the solution to my problem:

On Windows XP, all named kernel objects such as mutex, semaphore and memory mapped objects are stored in the same namespace. So when different processes in different user sessions reference a particular object using it's name, they obtain a handle to that object. However, as a security precaution, Windows terminal services creates a separate namespace for kernel objects referenced from processes started in it's session. Windows Vista has this behavior built into it as well, so that's why my app didn't work correctly on Vista. To elaborate, I have a Windows service that runs in the null session and an application that runs in a user session, so my named objects were being created in separate namespaces.

The quick fix for this issue was to use the Global namespace by prepending "Global\" to each kernel object name that I used and that did the trick.

歌入人心 2024-07-14 07:55:16

前缀“Global\”可能不适用于共享内存。 请参阅“会话 0 隔离对 Windows Vista 中的服务和驱动程序的影响” 寻求解决方案。

The prefix "Global\" may not work on shared memory. See "Impact of Session 0 Isolation on Services and Drivers in Windows Vista" for solution.

土豪我们做朋友吧 2024-07-14 07:55:16

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

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

What access are you opening the shared memory section with? Try with FILE_MAP_ALL_ACCESS and work your way down. Also make sure you don't have a race condition between the producer and consumers - which one is creating the shared memory? Make sure ths is created before the other one tries to open it. One method is to create the section in the parent before you start the child process - if you are using a parent/child architecture.

Your child may need to run elevated on Vista in order to be allowed access to the shared memory. It may also be related to the window session your are using. Services run in session 0 (I think) while other apps (especially if you log in via remote desktop) may run in another session.

轮廓§ 2024-07-14 07:55:16

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

Have you tried moving the file to a different location. Try putting it in the 'Shared Documents' folder, this seems to be the most freely accessible folder in Vista.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文