/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016--2017 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ #include #include #include "ptycon_memfn_impl.h" #include "ptycon_driver_impl.h" void * ptyc_calloc(size_t n, size_t size) { struct ptyc_memory_block block; if (!n || (size > (size_t)(-1) / n)) return 0; size *= n; size += 0xf; size &= ~(size_t)0xf; block.addr = 0; block.size = size + sizeof(block); if (ntapi->zw_allocate_virtual_memory( NT_CURRENT_PROCESS_HANDLE, &block.addr, 0, &block.size, NT_MEM_COMMIT, NT_PAGE_READWRITE)) return 0; block.used = size; block.avail = block.size - block.used; return (char *)block.addr + offsetof(struct ptyc_memory_block,buffer); } void * ptyc_balloc( struct ptyc_memory_block * cache, struct ptyc_memory_block * block, size_t n, size_t size) { char * baddr; void * addr = 0; if (!n || (size > (size_t)(-1) / n)) return 0; if (!cache || !cache->addr) addr = ptyc_calloc(n,size); size *= n; size += 0xf; size &= ~(size_t)0xf; if (size < block->avail) addr = ptyc_calloc(n,size); /* newly allocated block? */ if (addr) { baddr = addr; baddr -= offsetof(struct ptyc_memory_block,buffer); ntapi->tt_aligned_block_memcpy( (uintptr_t *)block, (uintptr_t *)baddr, sizeof(*block)); return addr; } /* cache */ addr = &block->buffer[block->used / sizeof(size_t)]; block->used += size; block->avail -= size; return addr; } void ptyc_free(void * addr) { struct ptyc_memory_block block; block.addr = addr; block.size = 0; ntapi->zw_free_virtual_memory( NT_CURRENT_PROCESS_HANDLE, &block.addr, &block.size, NT_MEM_RELEASE); }