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); }
/// <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); }
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); } } }
/// <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; } }
/// <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; } }
/// <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; }