Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does MapViewOfFile fail with ERROR_ACCESS_DENIED?

I came across this situation with WinAPI's MapViewOfFile function. An Internet search didn't turn up any apparent fixes, so I will share my problem and solution here.

Consider the following snippet:

const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
                                  NULL,
                                  PAGE_READWRITE,
                                  0,
                                  size,
                                  name);

if (!handle || handle == INVALID_HANDLE_VALUE)
    exit(GetLastError());

bool created = GetLastError() == 0;

void *block = MapViewOfFile( handle,
                             FILE_MAP_ALL_ACCESS,
                             0,
                             0,
                             size);

if (block == NULL)
    exit(GetLastError());

In one particular case, CreateFileMapping was successfully returning a handle. GetLastError was returning ERROR_ALREADY_EXISTS, so created == false. Now, the call to MapViewOfFile, using the same size that I passed to CreateFileMapping, returns NULL and GetLastError returns 0x05: ERROR_ACCESS_DENIED. The process was running with administrator privileges.

The MSDN documentation doesn't really mention any reason why this situation would occur. So why does CreateFileMapping succeed, but MapViewOfFile fail?

like image 969
Anthony Avatar asked Apr 16 '13 01:04

Anthony


2 Answers

After a lot of suffer, I finally found what was causing this error in my application, in case someone else is struggling with the same, the problem is not with the MapViewOfFile method, but with the CreateFileMapping, the size of the createFileMapping should be the size of the file, not the size of the element to read, if you don't know the size then it should be 0, this does not apply to the MapViewOfFile as the value to pass as size is the length of the block you want to read/write.

Your code working will look like this:

const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
                                  NULL,
                                  PAGE_READWRITE,
                                  0,
                                  0,
                                  name);

if (!handle || handle == INVALID_HANDLE_VALUE)
    exit(GetLastError());

bool created = GetLastError() == 0;

void *block = MapViewOfFile( handle,
                             FILE_MAP_ALL_ACCESS,
                             0,
                             0,
                             size);

if (block == NULL)
    exit(GetLastError());

A just putting this here to document what I found, unfortunately is hard to search for this error when you don't know what is causing it. I hope this saves a couple of hours to someone else.

like image 125
Cross Avatar answered Nov 05 '22 01:11

Cross


I'm sure there are many reasons why ERROR_ACCESS_DENIED could occur from a call to MapViewOfFile. In my particular situation, it was due to the size argument.

The hint is in the fact that created == false. It shows that the object "Global\\Object_Name" has already been created. For whatever reason, the creating call initialised the section with a smaller size. For what seems like an oversight, the second call to CreateFileMapping will happily give you a handle to the already-existing object, even if you asked for a bigger mapping.

The call to MapViewOfFile now fails, because it's requesting a view that is bigger than the actual section.

So, if you're in a similar situation where the second call to MapViewOfFile fails, check the size that you're trying to map to.

It could be that the second project is compiling with a different structure alignment, resulting in the sizeof() operator determining different values, or some other size-determining function is not behaving as expected.

like image 34
Anthony Avatar answered Nov 05 '22 02:11

Anthony