Esempio n. 1
0
        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);
        }
Esempio n. 2
0
 public MemorySlot(MemoryBlock ownerBlock, IntPtr address, int index)
 {
     this.ownerBlock = ownerBlock;
     Address         = address;
     Index           = index;
 }
Esempio n. 3
0
        public MemorySlot AllocateBuffer(IntPtr origin)
        {
            MemoryBlock block = GetMemoryBlock(origin);

            return(block.AllocateSlot());
        }