Inheritance: System.Runtime.InteropServices.SafeBuffer
 private MemoryMappedView(SafeMemoryMappedViewHandle viewHandle, long pointerOffset, long size, MemoryMappedFileAccess access)
 {
     this.m_viewHandle = viewHandle;
     this.m_pointerOffset = pointerOffset;
     this.m_size = size;
     this.m_access = access;
 }
Beispiel #2
0
 private unsafe MemoryMappedView(SafeMemoryMappedViewHandle viewHandle, long pointerOffset,
                                 long size, MemoryMappedFileAccess access)
 {
     _viewHandle = viewHandle;
     _pointerOffset = pointerOffset;
     _size = size;
     _access = access;
 }
        private unsafe MemoryMappedView(SafeMemoryMappedViewHandle viewHandle, Int64 pointerOffset, 
                                            Int64 size, MemoryMappedFileAccess access) {

            m_viewHandle = viewHandle;
            m_pointerOffset = pointerOffset;
            m_size = size;
            m_access = access;
        }
 /// <summary>
 /// Initialization of SafeMemoryMappedViewHandle by the filePath 
 /// </summary>
 /// <param name="dumpFileName">full path to dump file</param>
 public void Init(string dumpFileName)
 {
     using (FileStream fileStream = File.Open(dumpFileName, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read))
     {
         _safeMemoryMappedViewHandle = MemoryMapFileHandler.MapFile(fileStream, dumpFileName);
         GetSystemInfo();
     }
 }
		unsafe void CreatePosix (long offset, long size, MemoryMappedFileAccess access)
		{
			int offset_diff;

			MemoryMappedFile.MapPosix (file_handle, offset, ref size, access, out mmap_addr, out offset_diff);

			handle = new SafeMemoryMappedViewHandle ((IntPtr)((long)mmap_addr + offset_diff), size);
			Initialize (handle, 0, size, ToFileAccess (access));
		}
Beispiel #6
0
		unsafe void Create (IntPtr handle, long offset, long size, MemoryMappedFileAccess access)
		{
			IntPtr base_address;

			MemoryMapImpl.Map (handle, offset, ref size, access, out mmap_handle, out base_address);
			safe_handle = new SafeMemoryMappedViewHandle (mmap_handle, base_address, size);

			Initialize (safe_handle, 0, size, ToFileAccess (access));
		}
		unsafe void CreatePosix (FileStream file, long offset, long size, MemoryMappedFileAccess access) {
			long fsize = file.Length;

			if (size == 0 || size > fsize)
				size = fsize;

			int offset_diff;

			MemoryMappedFile.MapPosix (file, offset, size, access, out mmap_addr, out offset_diff, out mmap_size);

			handle = new SafeMemoryMappedViewHandle ((IntPtr)((long)mmap_addr + offset_diff), size);
		}
		internal unsafe static MemoryMappedView Create (IntPtr handle, long offset, long size, MemoryMappedFileAccess access)
		{
			IntPtr base_address;
			IntPtr mmap_handle;

			MemoryMapImpl.Map (handle, offset, ref size, access, out mmap_handle, out base_address);

			var safe_handle = new SafeMemoryMappedViewHandle (mmap_handle, base_address, size);

			// MemoryMapImpl.Map returns a base_address to the offset so MemoryMappedView is initiated
			// no offset.
			return new MemoryMappedView (safe_handle, 0, size, access);
		}
        /// <summary>
        /// Initialization of SafeMemoryMappedViewHandle by PID of live process
        /// </summary>
        /// <param name="pid">PID of life process</param>
        public void Init(uint pid)
        {
            var handle = Kernel32.Functions.OpenProcess(Kernel32.ProcessAccessFlags.All, false, pid);

            RecheckDirectory();

            string fileName = null;
            string fullfileName = GetDumpFileName(pid, ref fileName);

            using (FileStream fs = new FileStream(fullfileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
            {
                bool miniDumpCreated = Functions.MiniDumpWriteDump(handle, pid, fs.SafeFileHandle, MINIDUMP_TYPE.MiniDumpWithHandleData, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

                if (miniDumpCreated)
                {
                    _safeMemoryMappedViewHandle = MemoryMapFileHandler.MapFile(fs, fileName);
                }
            }
        }
Beispiel #10
0
 internal extern static UIntPtr VirtualQuery(SafeMemoryMappedViewHandle lpAddress, ref MEMORY_BASIC_INFORMATION lpBuffer, UIntPtr dwLength);
 private MemoryMappedView(SafeMemoryMappedViewHandle handle, long offset, long size)
 {
     this._handle = handle;
     this._offset = offset;
     this._size = size;
 }
 internal static extern IntPtr VirtualQuery(SafeMemoryMappedViewHandle address, ref MEMORY_BASIC_INFORMATION buffer, IntPtr sizeOfBuffer);
 internal static extern IntPtr VirtualAlloc(SafeMemoryMappedViewHandle address, UIntPtr numBytes, int commitOrReserve, int pageProtectionMode);
        public unsafe static MemoryMappedView CreateView(
            SafeMemoryMappedFileHandle memMappedFileHandle, MemoryMappedFileAccess access,
            long requestedOffset, long requestedSize)
        {
            if (requestedOffset > memMappedFileHandle._capacity)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (requestedSize > MaxProcessAddressSpace)
            {
                throw new IOException(SR.ArgumentOutOfRange_CapacityLargerThanLogicalAddressSpaceNotAllowed);
            }
            if (requestedOffset + requestedSize > memMappedFileHandle._capacity)
            {
                throw new UnauthorizedAccessException();
            }
            if (memMappedFileHandle.IsClosed)
            {
                throw new ObjectDisposedException(typeof(MemoryMappedFile).Name);
            }

            if (requestedSize == MemoryMappedFile.DefaultSize)
            {
                requestedSize = memMappedFileHandle._capacity - requestedOffset;
            }

            // mmap can only create views that start at a multiple of the page size. As on Windows,
            // we hide this restriction form the user by creating larger views than the user requested and hiding the parts
            // that the user did not request.  extraMemNeeded is the amount of extra memory we allocate before the start of the 
            // requested view. (mmap may round up the actual length such that it is also page-aligned; we hide that by using
            // the right size and not extending the size to be page-aligned.)
            ulong nativeSize;
            long extraMemNeeded, nativeOffset;
            long pageSize = Interop.Sys.SysConf(Interop.Sys.SysConfName._SC_PAGESIZE);
            Debug.Assert(pageSize > 0);
            ValidateSizeAndOffset(
                requestedSize, requestedOffset, pageSize,
                out nativeSize, out extraMemNeeded, out nativeOffset);

            // Determine whether to create the pages as private or as shared; the former is used for copy-on-write.
            Interop.Sys.MemoryMappedFlags flags =
                (memMappedFileHandle._access == MemoryMappedFileAccess.CopyOnWrite || access == MemoryMappedFileAccess.CopyOnWrite) ?
                Interop.Sys.MemoryMappedFlags.MAP_PRIVATE :
                Interop.Sys.MemoryMappedFlags.MAP_SHARED;

            // If we have a file handle, get the file descriptor from it.  If the handle is null,
            // we'll use an anonymous backing store for the map.
            SafeFileHandle fd;
            if (memMappedFileHandle._fileStream != null)
            {
                // Get the file descriptor from the SafeFileHandle
                fd = memMappedFileHandle._fileStream.SafeFileHandle;
                Debug.Assert(!fd.IsInvalid);
            }
            else
            {
                fd = new SafeFileHandle(new IntPtr(-1), false);
                flags |= Interop.Sys.MemoryMappedFlags.MAP_ANONYMOUS;
            }

            // Nothing to do for options.DelayAllocatePages, since we're only creating the map
            // with mmap when creating the view.

            // Verify that the requested view permissions don't exceed the map's permissions
            Interop.Sys.MemoryMappedProtections viewProtForVerification = GetProtections(access, forVerification: true);
            Interop.Sys.MemoryMappedProtections mapProtForVerification = GetProtections(memMappedFileHandle._access, forVerification: true);
            if ((viewProtForVerification & mapProtForVerification) != viewProtForVerification)
            {
                throw new UnauthorizedAccessException();
            }

            // viewProtections is strictly less than mapProtections, so use viewProtections for actually creating the map.
            Interop.Sys.MemoryMappedProtections viewProtForCreation = GetProtections(access, forVerification: false);

            // Create the map
            IntPtr addr = IntPtr.Zero;
            if (nativeSize > 0)
            {
                addr = Interop.Sys.MMap(
                    IntPtr.Zero,         // don't specify an address; let the system choose one
                    nativeSize,          // specify the rounded-size we computed so as to page align; size + extraMemNeeded
                    viewProtForCreation,
                    flags,
                    fd,                  // mmap adds a ref count to the fd, so there's no need to dup it.
                    nativeOffset);       // specify the rounded-offset we computed so as to page align; offset - extraMemNeeded
            }
            else
            {
                // There are some corner cases where the .NET API allows the requested size to be zero, e.g. the caller is 
                // creating a map at the end of the capacity.  We can't pass 0 to mmap, as that'll fail with EINVAL, nor can 
                // we create a map that extends beyond the end of the underlying file, as that'll fail on some platforms at the 
                // time of the map's creation.  Instead, since there's no data to be read/written, it doesn't actually matter 
                // what backs the view, so we just create an anonymous mapping.
                addr = Interop.Sys.MMap(
                    IntPtr.Zero,
                    1,         // any length that's greater than zero will suffice
                    viewProtForCreation,
                    flags | Interop.Sys.MemoryMappedFlags.MAP_ANONYMOUS,
                    new SafeFileHandle(new IntPtr(-1), false),        // ignore the actual fd even if there was one
                    0);
                requestedSize = 0;
                extraMemNeeded = 0;
            }
            if (addr == IntPtr.Zero) // note that shim uses null pointer, not non-null MAP_FAILED sentinel
            {
                throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo());
            }

            // Based on the HandleInheritability, try to prevent the memory-mapped region 
            // from being inherited by a forked process
            if (memMappedFileHandle._inheritability == HandleInheritability.None)
            {
                DisableForkingIfPossible(addr, nativeSize);
            }

            // Create and return the view handle
            var viewHandle = new SafeMemoryMappedViewHandle(addr, ownsHandle: true);
            viewHandle.Initialize((ulong)nativeSize);
            return new MemoryMappedView(
                viewHandle,
                extraMemNeeded,       // the view points to offset - extraMemNeeded, so we need to shift back by extraMemNeeded
                requestedSize,        // only allow access to the actual size requested
                access);
        }
 void Dispose(bool disposeManagedResources)
 {
     if (this._handle != null && !this._handle.IsClosed)
         this._handle.Dispose();
     this._handle = null;
 }
Beispiel #16
0
		private Win32MemoryMappedFile(FileStream fs, SafeMemoryMappedFileHandle handle, ulong size)
		{
			Contract.Requires(fs != null && handle != null && !handle.IsInvalid && !handle.IsClosed);
			m_mapHandle = handle;
			m_file = fs;
			m_size = size;

			// verify that it fits on 32 bit OS...
			if (IntPtr.Size == 4 && size > uint.MaxValue)
			{  // won't work with 32-bit pointers
				throw new InvalidOperationException("Memory mapped file size is too big to be opened on a 32-bit system.");
			}

			// verifiy that it will fit in the virtual address space of the process
			var totalVirtual = UnsafeNativeMethods.GetTotalVirtualAddressSpaceSize();
			if (size > totalVirtual)
			{
				throw new InvalidOperationException("Memory mapped file size is too big to fit in the current process virtual address space");
			}

			SafeMemoryMappedViewHandle view = null;
			byte* baseAddress = null;
			try
			{
				view = UnsafeNativeMethods.MapViewOfFile(m_mapHandle, UnsafeNativeMethods.FileMapAccess.FileMapRead, 0, 0, new UIntPtr(size));
				if (view.IsInvalid) throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
				view.Initialize(size);
				m_viewHandle = view;

				view.AcquirePointer(ref baseAddress);
				m_baseAddress = baseAddress;
			}
			catch
			{
				if (baseAddress != null) view.ReleasePointer();
				if (view != null) view.Dispose();
				m_file = null;
				m_viewHandle = null;
				m_mapHandle = null;
				m_baseAddress = null;
				throw;
			}
		}
        private void Test(SafeMemoryMappedViewHandle mappedFileView)
        {
            MINIDUMP_HANDLE_DATA_STREAM handleData;
            IntPtr streamPointer;
            IntPtr baseOfView;
            uint streamSize;

            var readStrem = SafeMemoryMappedViewStreamHandler.ReadStream(MINIDUMP_STREAM_TYPE.HandleDataStream, out handleData, out streamPointer, out streamSize, mappedFileView, out baseOfView);

            Assert.AreNotEqual(streamPointer, IntPtr.Zero);
            Assert.AreNotEqual(baseOfView, IntPtr.Zero);
            Assert.AreNotEqual(handleData.SizeOfHeader, 0);

            Assert.IsNotNull(handleData);

            var descriptor2 = handleData.SizeOfDescriptor == Marshal.SizeOf(typeof(MINIDUMP_HANDLE_DESCRIPTOR_2));
            var descriptor = handleData.SizeOfDescriptor == Marshal.SizeOf(typeof(MINIDUMP_HANDLE_DESCRIPTOR));

            if(!descriptor && !descriptor2)
            {
                Assert.Fail($"SizeOfDescriptor isn't as expected {handleData.SizeOfDescriptor }");
            }
        }
        public unsafe static MemoryMappedView CreateView(
            SafeMemoryMappedFileHandle memMappedFileHandle, MemoryMappedFileAccess access, 
            long requestedOffset, long requestedSize)
        {
            // If the requested size is either the default or if it's larger than the capacity
            // of the mapped file, reset it to be the capacity set when creating the mapped file.
            if (requestedSize == MemoryMappedFile.DefaultSize || requestedSize > memMappedFileHandle._capacity)
            {
                requestedSize = memMappedFileHandle._capacity;
            }
            Debug.Assert(requestedSize > 0);

            // mmap can only create views that start at a multiple of the page size. As on Windows,
            // we hide this restriction form the user by creating larger views than the user requested and hiding the parts
            // that the user did not request.  extraMemNeeded is the amount of extra memory we allocate before the start of the 
            // requested view. (mmap may round up the actual length such that it is also page-aligned; we hide that by using
            // the right size and not extending the size to be page-aligned.)
            ulong nativeSize, extraMemNeeded, nativeOffset;
            ValidateSizeAndOffset(
                requestedSize, requestedOffset, Interop.libc.sysconf(Interop.libc.SysConfNames._SC_PAGESIZE), 
                out nativeSize, out extraMemNeeded, out nativeOffset);

            bool gotRefOnHandle = false;
            try
            {
                // Determine whether to create the pages as private or as shared; the former is used for copy-on-write.
                Interop.libc.MemoryMappedFlags flags = (memMappedFileHandle._access == MemoryMappedFileAccess.CopyOnWrite) ?
                    Interop.libc.MemoryMappedFlags.MAP_PRIVATE :
                    Interop.libc.MemoryMappedFlags.MAP_SHARED;

                // If we have a file handle, get the file descriptor from it.  If the handle is null,
                // we'll use an anonymous backing store for the map.
                int fd;
                if (memMappedFileHandle._fileHandle != null)
                {
                    // Get the file descriptor from the SafeFileHandle
                    memMappedFileHandle._fileHandle.DangerousAddRef(ref gotRefOnHandle);
                    Debug.Assert(gotRefOnHandle);
                    fd = (int)memMappedFileHandle._fileHandle.DangerousGetHandle();
                    Debug.Assert(fd >= 0);
                }
                else
                {
                    Debug.Assert(!gotRefOnHandle);
                    fd = -1;
                    flags |= Interop.libc.MemoryMappedFlags.MAP_ANONYMOUS;
                }

                // Nothing to do for options.DelayAllocatePages, since we're only creating the map
                // with mmap when creating the view.

                // Intersect the permissions from the creation of the MMF and the MMV.
                Interop.libc.MemoryMappedProtections prot = GetProtections(memMappedFileHandle._access);
                prot &= GetProtections(access);
                if (prot == 0)
                {
                    throw new ArgumentOutOfRangeException("access");
                }

                // Create the map
                IntPtr addr = Interop.libc.mmap(
                    IntPtr.Zero,         // don't specify an address; let the system choose one
                    (IntPtr)nativeSize,  // specify the rounded-size we computed so as to page align; size + extraMemNeeded
                    prot,
                    flags,
                    fd,                  // mmap adds a ref count to the fd, so there's no need to dup it.
                    (long)nativeOffset); // specify the rounded-offset we computed so as to page align; offset - extraMemNeeded
                if ((long)addr < 0)
                {
                    throw Interop.GetExceptionForIoErrno(Marshal.GetLastWin32Error());
                }

                // Based on the HandleInheritability, try to prevent the memory-mapped region 
                // from being inherited by a forked process
                if (memMappedFileHandle._inheritability == HandleInheritability.None)
                {
                    int adviseResult = Interop.libc.madvise(addr, (IntPtr)nativeSize, Interop.libc.MemoryMappedAdvice.MADV_DONTFORK);
                    Debug.Assert(adviseResult == 0); // In release, ignore failures from advise; it's just a hint, anyway.
                }

                // Create and return the view handle
                var viewHandle = new SafeMemoryMappedViewHandle(addr, ownsHandle: true);
                viewHandle.Initialize(nativeSize);
                return new MemoryMappedView(
                    viewHandle, 
                    (long)extraMemNeeded, // the view points to offset - extraMemNeeded, so we need to shift back by extraMemNeeded
                    requestedSize,        // only allow access to the actual size requested
                    access);
            }
            finally
            {
                if (gotRefOnHandle)
                {
                    memMappedFileHandle._fileHandle.DangerousRelease();
                }
            }
        }