diff --git a/src/compat/alloc.c b/src/compat/alloc.c index 2480ef2..348de69 100644 --- a/src/compat/alloc.c +++ b/src/compat/alloc.c @@ -26,34 +26,30 @@ #include #ifdef VANILLA_WIN32 -HANDLE g_heap; +struct block { + void *ptr; + size_t size; + struct block *next; +}; + +struct block *g_blocks = NULL; void init_inheritable_heap(void) { - g_heap = HeapCreate(0, 0, 0); - if (g_heap == (HANDLE) NULL) { - fputs("Could not create the private inheritable heap.", stderr); - abort(); - } } int inherit_heap(HANDLE child_process) { - PROCESS_HEAP_ENTRY entry = { .lpData = NULL }; - - while (HeapWalk(g_heap, &entry)) { - if (!(entry.wFlags & PROCESS_HEAP_REGION)) - continue; - + for (struct block *b = g_blocks; b != NULL; b = b->next) { if (!VirtualAllocEx(child_process, - entry.lpData, - entry.cbData + entry.cbOverhead, + b->ptr, + b->size, MEM_COMMIT, PAGE_READWRITE)) return -1; if (!WriteProcessMemory(child_process, - entry.lpData, - entry.lpData, - entry.cbData + entry.cbOverhead, + b->ptr, + b->ptr, + b->size, NULL)) return -1; } @@ -63,7 +59,15 @@ int inherit_heap(HANDLE child_process) { void *cr_malloc(size_t size) { #ifdef VANILLA_WIN32 - return HeapAlloc(g_heap, 0, size); + void *ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + if (ptr == NULL) + return NULL; + struct block *b = malloc(sizeof (struct block)); + b->next = g_blocks; + b->ptr = ptr; + b->size = size; + g_blocks = b; + return ptr; #else return malloc(size); #endif @@ -71,7 +75,9 @@ void *cr_malloc(size_t size) { void *cr_calloc(size_t nmemb, size_t size) { #ifdef VANILLA_WIN32 - return HeapAlloc(g_heap, HEAP_ZERO_MEMORY, nmemb * size); + void *ptr = cr_malloc(nmemb * size); + memset(ptr, 0, nmemb * size); + return ptr; #else return calloc(nmemb, size); #endif @@ -79,7 +85,9 @@ void *cr_calloc(size_t nmemb, size_t size) { void *cr_realloc(void *ptr, size_t size) { #ifdef VANILLA_WIN32 - return HeapReAlloc(g_heap, 0, ptr, size); + if (size > 4096) + return NULL; + return ptr; #else return realloc(ptr, size); #endif @@ -87,7 +95,6 @@ void *cr_realloc(void *ptr, size_t size) { void cr_free(void *ptr) { #ifdef VANILLA_WIN32 - HeapFree(g_heap, 0, ptr); #else free(ptr); #endif