Windows 上的共享内存访问权限
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/176331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shared memory access permissions on Windows
提问by James Whetstone
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.
我开发了一个 Windows 应用程序,它使用共享内存---也就是---用于进程间通信的内存映射文件。我有一个 Windows 服务,它执行一些处理并定期将数据写入内存映射文件。我有一个单独的 Windows 应用程序,它从内存映射文件中读取并显示信息。该应用程序在 Windows XP、XP Pro 和 Server 2003 上按预期工作,但不适用于 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.
我可以看到正在写入内存映射文件的数据由 Windows 服务正确发生,因为我可以使用文本编辑器打开文件并查看存储的消息,但“消费者”应用程序无法从文件中读取。这里要注意的一件有趣的事情是,如果我关闭消费者应用程序并重新启动它,它会消耗之前写入内存映射文件的消息。
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.
此外,另一件奇怪的事情是,当我使用远程桌面连接到 Windows 主机并通过远程桌面调用/使用消费者应用程序时,我得到了相同的行为。但是,如果我调用远程桌面并使用以下命令连接到目标主机的控制台会话:mstsc -v:servername /F -console
,一切正常。
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:
我用来创建内存映射文件和同步访问的互斥对象的 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 think this may be part of the issue.
我认为这可能是问题的一部分。
回答by James Whetstone
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.
在 Windows XP 上,所有命名的内核对象(例如互斥锁、信号量和内存映射对象)都存储在同一个命名空间中。因此,当不同用户会话中的不同进程使用其名称引用特定对象时,它们会获得该对象的句柄。但是,作为安全预防措施,Windows 终端服务会为从其会话中启动的进程引用的内核对象创建一个单独的命名空间。Windows Vista 也内置了这种行为,所以这就是我的应用程序在 Vista 上无法正常工作的原因。详细地说,我有一个在空会话中运行的 Windows 服务和一个在用户会话中运行的应用程序,所以我的命名对象是在不同的命名空间中创建的。
The quick fix for this issue was to use the Global namespace by prepending "Global\" to each kernel object namethat I used and that did the trick.
这个问题的快速解决方法是通过在我使用的每个内核对象名称前加上“Global\”来使用 Global 命名空间,这就是诀窍。
回答by James Whetstone
The prefix "Global\" may not work on shared memory. See "Impact of Session 0 Isolation on Services and Drivers in Windows Vista"for solution.
前缀“Global\”可能不适用于共享内存。有关解决方案,请参阅“会话 0 隔离对 Windows Vista 中的服务和驱动程序的影响”。
回答by 1800 INFORMATION
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.
您使用什么访问权限打开共享内存部分?尝试FILE_MAP_ALL_ACCESS
并按照自己的方式工作。还要确保生产者和消费者之间没有竞争条件 - 哪个正在创建共享内存?确保在另一个尝试打开它之前创建了它。一种方法是在启动子进程之前在父进程中创建该部分 - 如果您使用的是父/子架构。
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.
您的孩子可能需要在 Vista 上运行提升才能访问共享内存。它也可能与您正在使用的窗口会话有关。服务在会话 0(我认为)中运行,而其他应用程序(特别是如果您通过远程桌面登录)可能在另一个会话中运行。
回答by jmatthias
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.
您是否尝试将文件移动到其他位置。尝试将其放在“共享文档”文件夹中,这似乎是 Vista 中最可自由访问的文件夹。