`mscomctl.ocx` (part of the VB6 common controls) calls `HeapCreate(0x04000000,1,0)`, that flag is the old and undocumented `HEAP_SHARED`. `HEAP_CreateSystemHeap()` tries to map memory at `0x80000000`, this fails on Wow64 (and probably should for all 32-bit platforms for non-LAA EXEs).
As a workaround, map the memory anywhere if it fails at `0x80000000`.
I wasn't able to find much documentation about `HEAP_SHARED`, it dates back to Win9x and I guess Wine may have needed it for some native DLLs. It's not clear whether modern Windows really implements any shared heap functionality any more, every 'shared' heap created returns a different pointer (even in the same process). Maybe Wine should remove the functionality too?
From: Brendan Shanks bshanks@codeweavers.com
--- dlls/kernel32/heap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c index a2910688e44..7e860748412 100644 --- a/dlls/kernel32/heap.c +++ b/dlls/kernel32/heap.c @@ -68,11 +68,13 @@ static inline HANDLE HEAP_CreateSystemHeap(void) 0, SYSTEM_HEAP_SIZE, "__wine_system_heap" ))) return 0; created = (GetLastError() != ERROR_ALREADY_EXISTS);
- if (!(base = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, SYSTEM_HEAP_BASE ))) + base = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, SYSTEM_HEAP_BASE ); + if (!base) { - /* pre-defined address not available */ - ERR( "system heap base address %p not available\n", SYSTEM_HEAP_BASE ); - return 0; + /* pre-defined address not available, map anywhere */ + WARN( "system heap base address %p not available\n", SYSTEM_HEAP_BASE ); + if (!(base = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL ))) + return 0; }
if (created) /* newly created heap */
Maybe Wine should remove the functionality too?
IIRC it was needed for native DCOM which we no longer support, so yes, it could probably be removed.