Memory mapped files from XP to Vista
So you have an NT service and a user application that share date through memory mapped files. It has worked for years. It even survived XP SP2. Now Vista comes along and boom. No more. Let's see what's up.
You create your memory mapped file from your service. Something like this:
HANDLE mmfile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
upperSize,
lowerSize,
L"MaartensMap" );
And then from your user application you connect to it like so:
HANDLE mmfile = OpenFileMapping (
FILE_MAP_ALL_ACCESS,
FALSE,
L"MaartensMap" );
In Vista GetLastError() will return 2 (ERROR_FILE_NOT_FOUND). Hmm. Where did it go?
Let's look at where the file gets created on XP. Process Explorer shows this for XP:
And this for Vista:
That gives us no clue whatsoever. Identical as far as I can tell. Let's run the server code on both XP and Vista in the user session and see what Process Explorer makes of that. This might give us a clue how the client side user application will look for the memory mapped file. Here is the XP version:
And here is the one on Vista:
Oopsie. That looks different. Suppose that the client application is actually looking under this same name. No wonder that you would get an File not Found error. The names are different. Online search for "sessions\1\basenamedobject" gives hits that point to Terminal Services. There appear to be Local Global and Session namespaces. So prior to Vista and Server 2008 all services shared the same namespace as the first user logging in to the machine. This was session 0. With Vista this is no longer the case. Just like all compatibility issues it is explained in the cookbook.
Apparently if I want to keep this working I wil need to prefix my name with Global. Let's give that a try.
You will see in Process Explorer that the named object created from the service still looks the same. When you try opening it from the user mode application, you will get a different error: 5 this time. That means Access Denied, but at least we were able to find the file. Progress. The reason we get Access Denied is because we set a standard ACL on the memory mapped file and then from the user application we try to open it with All Access. So there is still some work to be done. But that is outside the scope of this blog. J A quick fix could be to open the file on the client size with only read only. But that will imply one-way traffic.
So we have sessions you say. And somewhere you read that Fast User Switching makes use of those sessions. But wait, FUS existed in the XP days as well! Why didn't that break things then, hmm? Hmm, dunno. Maybe it did. So back to the XP machine and make sure to log in as a different user while keeping the initial session alive. Running the server and trying to hook up the client gives us the initial Error 2: file not found. And when running the server side code from within a user app shows the familiar: "Sessions\1\BaseNamedObjects\MaartensMap". Conclusion: this is not a new issue but a lot more visible due to Session 0 isolation.
Comments
- Anonymous
February 20, 2011
It would have been really helpful if you had been able to go more in depth regarding the error 5 access denied problem but thanks for offering some hints. I only hope i find a solution this afternoon. Cheers.