Example #1
0
            public static void Mmap(MemoryMappedFileStreamCreator creator, bool mapAsImage)
            {
                using (var fileHandle = CreateFile(creator.theFileName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero))
                {
                    if (fileHandle.IsInvalid)
                        throw new IOException(string.Format("Could not open file {0} for reading. Error: {1:X8}", creator.theFileName, Marshal.GetLastWin32Error()));

                    uint sizeHi;
                    uint sizeLo = GetFileSize(fileHandle, out sizeHi);
                    int hr;
                    if (sizeLo == INVALID_FILE_SIZE && (hr = Marshal.GetLastWin32Error()) != NO_ERROR)
                        throw new IOException(string.Format("Could not get file size. File: {0}, error: {1:X8}", creator.theFileName, hr));
                    var fileSize = ((long)sizeHi << 32) | sizeLo;

                    using (var fileMapping = CreateFileMapping(fileHandle, IntPtr.Zero, PAGE_READONLY | (mapAsImage ? SEC_IMAGE : 0), 0, 0, null))
                    {
                        if (fileMapping.IsInvalid)
                            throw new MemoryMappedIONotSupportedException(string.Format("Could not create a file mapping object. File: {0}, error: {1:X8}", creator.theFileName, Marshal.GetLastWin32Error()));
                        creator.data = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, UIntPtr.Zero);
                        if (creator.data == IntPtr.Zero)
                            throw new MemoryMappedIONotSupportedException(string.Format("Could not map file {0}. Error: {1:X8}", creator.theFileName, Marshal.GetLastWin32Error()));
                        creator.dataLength = fileSize;
                        creator.osType = OSType.Windows;
                    }
                }
            }
Example #2
0
        /// <summary>
        /// Creates a new <see cref="MemoryMappedFileStreamCreator"/> if supported or returns
        /// <c>null</c> if the OS functions aren't supported.
        /// </summary>
        /// <remarks>If <paramref name="mapAsImage"/> is <c>true</c>, then the created
        /// <see cref="UnmanagedMemoryStreamCreator"/> that is used internally by the class,
        /// can only access bytes up to the file size, not to the end of the mapped image. You must
        /// set <see cref="UnmanagedMemoryStreamCreator.Length"/> to the correct image length to access the full image.</remarks>
        /// <param name="fileName">Name of the file</param>
        /// <param name="mapAsImage">NOT SUPPORTED. <c>true</c> if we should map it as an executable</param>
        /// <exception cref="IOException">If we can't open/map the file</exception>
        internal static MemoryMappedFileStreamCreator CreateUnix(string fileName, bool mapAsImage)
        {
            if (!canTryUnix)
                return null;

            var creator = new MemoryMappedFileStreamCreator();
            creator.theFileName = GetFullPath(fileName);
            try
            {
                Unix.Mmap(creator, mapAsImage);
                if (mapAsImage)
                { // Only check this if we know that mmap() works, i.e., if above call succeeds
                    creator.Dispose();
                    throw new ArgumentException("mapAsImage == true is not supported on this OS");
                }
                return creator;
            }
            catch (MemoryMappedIONotSupportedException ex)
            {
                Debug.WriteLine(string.Format("mmap'd IO didn't work: {0}", ex.Message));
            }
            catch (EntryPointNotFoundException)
            {
            }
            catch (DllNotFoundException)
            {
            }
            canTryUnix = false;
            return null;
        }
 private static MemoryMappedFileStreamCreator CreateMemoryMappedFileStreamCreator(string fileName, bool mapAsImage)
 {
     if (!isUnix)
     {
         return(MemoryMappedFileStreamCreator.CreateWindows(fileName, mapAsImage));
     }
     else
     {
         return(MemoryMappedFileStreamCreator.CreateUnix(fileName, mapAsImage));
     }
 }
Example #4
0
            public static void Mmap(MemoryMappedFileStreamCreator creator, bool mapAsImage)
            {
                int fd = open(creator.theFileName, O_RDONLY);
                try
                {
                    if (fd < 0)
                        throw new IOException(string.Format("Could not open file {0} for reading. Error: {1}", creator.theFileName, fd));

                    long size;
                    IntPtr data;

                    if (IntPtr.Size == 4)
                    {
                        size = lseek32(fd, 0, SEEK_END);
                        if (size == -1)
                            throw new MemoryMappedIONotSupportedException(string.Format("Could not get length of {0} (lseek failed): {1}", creator.theFileName, Marshal.GetLastWin32Error()));

                        data = mmap32(IntPtr.Zero, (IntPtr)size, PROT_READ, MAP_PRIVATE, fd, 0);
                        if (data == new IntPtr(-1) || data == IntPtr.Zero)
                            throw new MemoryMappedIONotSupportedException(string.Format("Could not map file {0}. Error: {1}", creator.theFileName, Marshal.GetLastWin32Error()));
                    }
                    else
                    {
                        size = lseek64(fd, 0, SEEK_END);
                        if (size == -1)
                            throw new MemoryMappedIONotSupportedException(string.Format("Could not get length of {0} (lseek failed): {1}", creator.theFileName, Marshal.GetLastWin32Error()));

                        data = mmap64(IntPtr.Zero, (IntPtr)size, PROT_READ, MAP_PRIVATE, fd, 0);
                        if (data == new IntPtr(-1) || data == IntPtr.Zero)
                            throw new MemoryMappedIONotSupportedException(string.Format("Could not map file {0}. Error: {1}", creator.theFileName, Marshal.GetLastWin32Error()));
                    }

                    creator.data = data;
                    creator.dataLength = size;
                    creator.origDataLength = creator.dataLength;
                    creator.osType = OSType.Unix;
                }
                finally
                {
                    if (fd >= 0)
                        close(fd);
                }
            }
Example #5
0
        /// <summary>
        /// Creates a new <see cref="MemoryMappedFileStreamCreator"/> if supported or returns
        /// <c>null</c> if the OS functions aren't supported.
        /// </summary>
        /// <remarks>If <paramref name="mapAsImage"/> is <c>true</c>, then the created
        /// <see cref="UnmanagedMemoryStreamCreator"/> that is used internally by the class,
        /// can only access bytes up to the file size, not to the end of the mapped image. You must
        /// set <see cref="UnmanagedMemoryStreamCreator.Length"/> to the correct image length to access the full image.</remarks>
        /// <param name="fileName">Name of the file</param>
        /// <param name="mapAsImage"><c>true</c> if we should map it as an executable</param>
        /// <exception cref="IOException">If we can't open/map the file</exception>
        internal static MemoryMappedFileStreamCreator CreateWindows(string fileName, bool mapAsImage)
        {
            if (!canTryWindows)
                return null;

            var creator = new MemoryMappedFileStreamCreator();
            creator.theFileName = GetFullPath(fileName);
            try
            {
                Windows.Mmap(creator, mapAsImage);
                return creator;
            }
            catch (EntryPointNotFoundException)
            {
            }
            catch (DllNotFoundException)
            {
            }
            canTryWindows = false;
            return null;
        }