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.
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.