views:

1975

answers:

5

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?

A: 

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.

jmatthias
Shared documents is a highly insecure location for IPC related files - do not do this.
1800 INFORMATION
A: 

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.

1800 INFORMATION
So I am using FILE_MAP_ALL_ACCESS to map the shared memory and I've designed the code so that it doesn't matter who creates the shared memory first. But your suggestion about the session is interesting. I'll look into this.
James Whetstone
A: 

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.

James Whetstone
+3  A: 

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. Vista has the 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. So the quick fix for this issue was to use the Global namespace by prepending "Globa\" to each kernel object name that I used and that did the trick.

James Whetstone
You have probably created a security hole on your system.
Sanjaya R
Well there are mixed thoughts on that one. There are times when you want to give a service higher rights and ability ( say Local System) than a user application which needs to be able to interface with that service. Arguable you are enabling security by only giving the service and not the app all that access. However you can view the fact that the service exists at all as a potential security hole. But I disagree.
Dan
+1  A: 

profix "Global\" may not work on shared memory, you can google document "Impact of Session 0 Isolation on Services and Drivers in Windows Vista" for solution.

This document validates my solutions...it states "The correct way for user applications to synchronize with a service is to explicitly use the Global\ prefix".
James Whetstone