MemoryBlock GetMemoryBlock(IntPtr origin) { IntPtr minAddr = IntPtr.Zero; IntPtr maxAddr = IntPtr.Zero; MemoryBlock result = null; SYSTEM_INFO si = new SYSTEM_INFO(); GetSystemInfo(ref si); if (IntPtr.Size == 8) { minAddr = si.lpMinimumApplicationAddress; maxAddr = si.lpMaximumApplicationAddress; if ((ulong)origin > MAX_MEMORY_RANGE && (ulong)minAddr < (ulong)origin - MAX_MEMORY_RANGE) { minAddr = (IntPtr)((ulong)origin - MAX_MEMORY_RANGE); } if ((ulong)maxAddr > (ulong)origin + MAX_MEMORY_RANGE) { maxAddr = (IntPtr)((ulong)origin + MAX_MEMORY_RANGE); } maxAddr = (IntPtr)((ulong)maxAddr - MEMORY_BLOCK_SIZE - 1); } foreach (var memoryBlock in memoryBlocks) { if (IntPtr.Size == 8 && ((ulong)memoryBlock.BaseAddress < (ulong)minAddr || (ulong)memoryBlock.BaseAddress >= (ulong)maxAddr)) { continue; } if (!memoryBlock.IsFull()) { return(memoryBlock); } } //Couldn't find a free block, lets allocate another if (IntPtr.Size == 8) { IntPtr alloc = origin; while ((ulong)alloc >= (ulong)minAddr) { alloc = FindPrevFreeRegion(alloc, minAddr, si.dwAllocationGranularity); if (alloc == IntPtr.Zero) { break; } IntPtr baseAddr = VirtualAlloc(alloc, (IntPtr)MEMORY_BLOCK_SIZE, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite); if (baseAddr != IntPtr.Zero) { result = new MemoryBlock(baseAddr); break; } } if (result == null) { alloc = origin; while ((ulong)alloc <= (ulong)maxAddr) { alloc = FindNextFreeRegion(alloc, maxAddr, si.dwAllocationGranularity); if (alloc == IntPtr.Zero) { break; } IntPtr baseAddr = VirtualAlloc(alloc, (IntPtr)MEMORY_BLOCK_SIZE, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite); if (baseAddr != IntPtr.Zero) { result = new MemoryBlock(baseAddr); break; } } } } else { IntPtr baseAddr = VirtualAlloc(IntPtr.Zero, (IntPtr)MEMORY_BLOCK_SIZE, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite); if (baseAddr == IntPtr.Zero) { throw new OutOfMemoryException("Failed to allocate new block of memory"); } result = new MemoryBlock(baseAddr); } if (result == null) { throw new OutOfMemoryException("Failed to allocate new block of memory"); } memoryBlocks.Add(result); return(result); }
public MemorySlot(MemoryBlock ownerBlock, IntPtr address, int index) { this.ownerBlock = ownerBlock; Address = address; Index = index; }
public MemorySlot AllocateBuffer(IntPtr origin) { MemoryBlock block = GetMemoryBlock(origin); return(block.AllocateSlot()); }