Search code examples
c#.net.net-4.0memory-mapped-files

MemoryMappedFile.CreateFromFile always throws UnauthorizedAccessException


I realize .NET 4.0 is in Beta, but I'm hoping someone has a resolution for this. I'm trying to create a memory mapped file from a DLL:

FileStream file = File.OpenRead("C:\mydll.dll");
using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateFromFile(file,
    "PEIMAGE", 1024 * 1024, MemoryMappedFileAccess.ReadExecute))
{
    using (MemoryMappedViewStream viewStream = mappedFile.CreateViewStream())
    {
        // read from the view stream
    }
}

Unfortunately, no matter what I do, I always get an UnauthorizedAccessException, for which the MSDN documentation states:

The operating system denied the specified access to the file; for example, access is set to Write or ReadWrite, but the file or directory is read-only.

I've monitored my application with Sysinternals Process Monitor, which shows that the file is indeed being opened successfully. I've also tried memory mapping other non-DLL files, but with the same result.


Solution

  • Well, I've got an example based on the above which runs without exceptions. I've made two important changes:

    • I'm only specified MemoryMappedFileAccess.Read when creating the MemoryMappedFile. You've opened it for read, so you can only read. I haven't tried fixing it to allow execute as well by changing how the FileStream is opened.
    • I've made the CreateViewStream call explicitly use MemoryMappedFileAccess.Read as well. I'm not sure why it doesn't use the existing access rights by itself, but there we go.

    Full program:

    using System.IO;
    using System.IO.MemoryMappedFiles;
    
    class Test
    {
        static void Main()
        {
            FileStream file = File.OpenRead("Test.cs");
            using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateFromFile
                   (file, "PEIMAGE", file.Length, MemoryMappedFileAccess.Read, null, 0, false))
            {
                using (var viewStream = mappedFile.CreateViewStream
                       (0, file.Length, MemoryMappedFileAccess.Read))
                {
                    // read from the view stream
                }
            }
        }
    }