7
votes

I have an application which has a shared memory zone defined with CreateFileMapping and I am trying to read that memory from another application.

I tried this:

handle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
             0,$3200, pchar('FileMappingZone'));

But I get:

Cannot create a file when that file already exists

What could be the problem?

1
Does your wrapper around winapi calls check GetLastError unconditionally after each call? It's expected for CreateFileMapping to return a valid handle and for the following GetLastError to return ERROR_ALREADY_EXISTS (which is not actually an error if it's what you expect).Anton Kovalenko
I call GetLastError just after the call on CreateFileMapping, if I close the application that has created the file mapping before it says : Operation completed succesefullyopc0de
@opc0de Don't do that. Only call GetLastError when the documentation says to do so. And that is when CreateFileMapping returns NULL.David Heffernan
@DavidHeffernan GetLastError is supposed to be examined in non-error cases sometimes, unlike errno. But then it's important not to interpret its value as an error.Anton Kovalenko

1 Answers

15
votes

Not everything which sets GetLastError() value to non-success is an error. It's important to distinguish errors by function's return value first, and examine GetLastError() to get more information on the kind of error that happened.

For mappings that already exist, CreateFileMapping is documented to return a valid handle and to set GetLastError() value to ERROR_ALREADY_EXISTS. In this case, error value is informational: it's valid to examine it if you're interested whether the mapping was existing before you opened it, but it's not an error. You detect failure by testing the return value for being NULL. Otherwise you just go ahead and use the handle.

P.S. If you want to ensure that the section exists before opening, you may use OpenFileMapping which will fail for non-existing sections instead of creating a new one.