Beispiel #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;
                    }
                }
            }
        /// <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 (EntryPointNotFoundException) {
            }
            catch (DllNotFoundException) {
            }
            canTryUnix = false;
            return(null);
        }
Beispiel #3
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));
                //TODO: The lseek() and mmap() fails on MacOS.
            }
            catch (EntryPointNotFoundException) {
            }
            catch (DllNotFoundException) {
            }
            canTryUnix = false;
            return(null);
        }
Beispiel #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));
                    }

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

                    var data = mmap(IntPtr.Zero, size, PROT_READ, MAP_PRIVATE, fd, IntPtr.Zero);
                    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.ToInt64();
                    creator.origDataLength = creator.dataLength;
                    creator.osType         = OSType.Unix;
                }
                finally {
                    if (fd >= 0)
                    {
                        close(fd);
                    }
                }
            }
 private static MemoryMappedFileStreamCreator CreateMemoryMappedFileStreamCreator(string fileName, bool mapAsImage)
 {
     if (!isUnix)
     {
         return(MemoryMappedFileStreamCreator.CreateWindows(fileName, mapAsImage));
     }
     return(MemoryMappedFileStreamCreator.CreateUnix(fileName, mapAsImage));
 }
            public static void Mmap(MemoryMappedFileStreamCreator creator, bool mapAsImage)
            {
                int fd = Load(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);
                    }
                }
            }
Beispiel #7
0
		/// <summary>
		/// Creates a <see cref="IImageStream"/>
		/// </summary>
		/// <param name="fileName">Filename</param>
		/// <param name="mapAsImage"><c>true</c> if we should map it as an executable</param>
		/// <returns>A new <see cref="IImageStream"/> instance</returns>
		public static IImageStream CreateImageStream(string fileName, bool mapAsImage) {
			if (doesNotSupportMmapFileMethods)
				return MemoryImageStream.Create(File.ReadAllBytes(fileName));

			var creator = new MemoryMappedFileStreamCreator(fileName, mapAsImage);
			try {
				return new UnmanagedMemoryImageStream(creator);
			}
			catch {
				if (creator != null)
					creator.Dispose();
				throw;
			}
		}
Beispiel #8
0
        /// <summary>
        /// Creates a <see cref="IImageStream"/>
        /// </summary>
        /// <param name="fileName">Filename</param>
        /// <param name="mapAsImage"><c>true</c> if we should map it as an executable</param>
        /// <returns>A new <see cref="IImageStream"/> instance</returns>
        public static IImageStream CreateImageStream(string fileName, bool mapAsImage)
        {
            if (doesNotSupportMmapFileMethods)
            {
                return(MemoryImageStream.Create(File.ReadAllBytes(fileName)));
            }

            var creator = new MemoryMappedFileStreamCreator(fileName, mapAsImage);

            try {
                return(new UnmanagedMemoryImageStream(creator));
            }
            catch {
                if (creator != null)
                {
                    creator.Dispose();
                }
                throw;
            }
        }
Beispiel #9
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);
        }
			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;
					}
				}
			}
		/// <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));
				//TODO: The lseek() and mmap() fails on MacOS.
			}
			catch (EntryPointNotFoundException) {
			}
			catch (DllNotFoundException) {
			}
			canTryUnix = false;
			return null;
		}
		/// <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;
		}
			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));

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

					var data = mmap(IntPtr.Zero, size, PROT_READ, MAP_PRIVATE, fd, IntPtr.Zero);
					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.ToInt64();
					creator.origDataLength = creator.dataLength;
					creator.osType = OSType.Unix;
				}
				finally {
					if (fd >= 0)
						close(fd);
				}
			}
        /// <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 (EntryPointNotFoundException) {
            }
            catch (DllNotFoundException) {
            }
            canTryUnix = false;
            return null;
        }