Share the system heap between different address spaces. Made process
heap per-address space instead of per-process.
This commit is contained in:
parent
2fe57779fb
commit
079fd72ca7
|
@ -22,6 +22,7 @@ extern LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str );
|
||||||
extern LPWSTR HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str );
|
extern LPWSTR HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str );
|
||||||
extern LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str );
|
extern LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str );
|
||||||
extern LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str );
|
extern LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str );
|
||||||
|
extern BOOL HEAP_CreateSystemHeap(void);
|
||||||
|
|
||||||
/* SEGPTR helper macros */
|
/* SEGPTR helper macros */
|
||||||
|
|
||||||
|
@ -41,5 +42,18 @@ static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) {
|
||||||
#define SEGPTR_FREE(ptr) \
|
#define SEGPTR_FREE(ptr) \
|
||||||
(HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0)
|
(HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0)
|
||||||
|
|
||||||
|
/* system heap private data */
|
||||||
|
/* you must lock the system heap before using this structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *gdi; /* GDI heap */
|
||||||
|
void *user; /* USER handle table */
|
||||||
|
void *cursor; /* cursor information */
|
||||||
|
void *queue; /* message queues descriptor */
|
||||||
|
void *win; /* windows descriptor */
|
||||||
|
void *root; /* X11 root window */
|
||||||
|
} SYSTEM_HEAP_DESCR;
|
||||||
|
|
||||||
|
extern SYSTEM_HEAP_DESCR *SystemHeapDescr;
|
||||||
|
|
||||||
#endif /* __WINE_HEAP_H */
|
#endif /* __WINE_HEAP_H */
|
||||||
|
|
|
@ -151,7 +151,7 @@ void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value );
|
||||||
extern DWORD WINAPI MapProcessHandle( HANDLE handle );
|
extern DWORD WINAPI MapProcessHandle( HANDLE handle );
|
||||||
|
|
||||||
/* scheduler/environ.c */
|
/* scheduler/environ.c */
|
||||||
extern BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env );
|
extern BOOL ENV_InheritEnvironment( LPCSTR env );
|
||||||
extern void ENV_FreeEnvironment( PDB *pdb );
|
extern void ENV_FreeEnvironment( PDB *pdb );
|
||||||
|
|
||||||
/* scheduler/process.c */
|
/* scheduler/process.c */
|
||||||
|
|
|
@ -117,6 +117,7 @@ typedef struct _SINGLE_LIST_ENTRY {
|
||||||
#define HEAP_WINE_SEGPTR 0x01000000 /* Not a Win32 flag */
|
#define HEAP_WINE_SEGPTR 0x01000000 /* Not a Win32 flag */
|
||||||
#define HEAP_WINE_CODESEG 0x02000000 /* Not a Win32 flag */
|
#define HEAP_WINE_CODESEG 0x02000000 /* Not a Win32 flag */
|
||||||
#define HEAP_WINE_CODE16SEG 0x04000000 /* Not a Win32 flag */
|
#define HEAP_WINE_CODE16SEG 0x04000000 /* Not a Win32 flag */
|
||||||
|
#define HEAP_WINE_SHARED 0x08000000 /* Not a Win32 flag */
|
||||||
|
|
||||||
/* Processor feature flags. */
|
/* Processor feature flags. */
|
||||||
#define PF_FLOATING_POINT_PRECISION_ERRATA 0
|
#define PF_FLOATING_POINT_PRECISION_ERRATA 0
|
||||||
|
|
|
@ -78,7 +78,7 @@ static BOOL ENV_BuildEnvironment( PDB *pdb )
|
||||||
|
|
||||||
/* Now allocate the environment */
|
/* Now allocate the environment */
|
||||||
|
|
||||||
if (!(p = HeapAlloc( SystemHeap, 0, size ))) return FALSE;
|
if (!(p = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
|
||||||
pdb->env_db->environ = p;
|
pdb->env_db->environ = p;
|
||||||
|
|
||||||
/* And fill it with the Unix environment */
|
/* And fill it with the Unix environment */
|
||||||
|
@ -102,11 +102,12 @@ static BOOL ENV_BuildEnvironment( PDB *pdb )
|
||||||
* Make a process inherit the environment from its parent or from an
|
* Make a process inherit the environment from its parent or from an
|
||||||
* explicit environment.
|
* explicit environment.
|
||||||
*/
|
*/
|
||||||
BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env )
|
BOOL ENV_InheritEnvironment( LPCSTR env )
|
||||||
{
|
{
|
||||||
DWORD size;
|
DWORD size;
|
||||||
LPCSTR src;
|
LPCSTR src;
|
||||||
LPSTR dst;
|
LPSTR dst;
|
||||||
|
PDB *pdb = PROCESS_Current();
|
||||||
|
|
||||||
/* FIXME: should lock the parent environment */
|
/* FIXME: should lock the parent environment */
|
||||||
if (!env)
|
if (!env)
|
||||||
|
@ -131,7 +132,7 @@ BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env )
|
||||||
|
|
||||||
/* Copy the environment */
|
/* Copy the environment */
|
||||||
|
|
||||||
if (!(pdb->env_db->environ = HeapAlloc( pdb->heap, 0, size )))
|
if (!(pdb->env_db->environ = HeapAlloc( GetProcessHeap(), 0, size )))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
pdb->env_db->env_sel = SELECTOR_AllocBlock( pdb->env_db->environ,
|
pdb->env_db->env_sel = SELECTOR_AllocBlock( pdb->env_db->environ,
|
||||||
0x10000, SEGMENT_DATA,
|
0x10000, SEGMENT_DATA,
|
||||||
|
@ -162,7 +163,7 @@ void ENV_FreeEnvironment( PDB *pdb )
|
||||||
if (!pdb->env_db) return;
|
if (!pdb->env_db) return;
|
||||||
if (pdb->env_db->env_sel) SELECTOR_FreeBlock( pdb->env_db->env_sel, 1 );
|
if (pdb->env_db->env_sel) SELECTOR_FreeBlock( pdb->env_db->env_sel, 1 );
|
||||||
DeleteCriticalSection( &pdb->env_db->section );
|
DeleteCriticalSection( &pdb->env_db->section );
|
||||||
HeapFree( pdb->heap, 0, pdb->env_db );
|
/* the storage will be deleted when the process heap is destroyed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,7 +183,7 @@ LPCWSTR WINAPI GetCommandLineW(void)
|
||||||
PDB *pdb = PROCESS_Current();
|
PDB *pdb = PROCESS_Current();
|
||||||
EnterCriticalSection( &pdb->env_db->section );
|
EnterCriticalSection( &pdb->env_db->section );
|
||||||
if (!pdb->env_db->cmd_lineW)
|
if (!pdb->env_db->cmd_lineW)
|
||||||
pdb->env_db->cmd_lineW = HEAP_strdupAtoW( pdb->heap, 0,
|
pdb->env_db->cmd_lineW = HEAP_strdupAtoW( GetProcessHeap(), 0,
|
||||||
pdb->env_db->cmd_line );
|
pdb->env_db->cmd_line );
|
||||||
LeaveCriticalSection( &pdb->env_db->section );
|
LeaveCriticalSection( &pdb->env_db->section );
|
||||||
return pdb->env_db->cmd_lineW;
|
return pdb->env_db->cmd_lineW;
|
||||||
|
@ -209,8 +210,8 @@ LPWSTR WINAPI GetEnvironmentStringsW(void)
|
||||||
PDB *pdb = PROCESS_Current();
|
PDB *pdb = PROCESS_Current();
|
||||||
|
|
||||||
EnterCriticalSection( &pdb->env_db->section );
|
EnterCriticalSection( &pdb->env_db->section );
|
||||||
size = HeapSize( pdb->heap, 0, pdb->env_db->environ );
|
size = HeapSize( GetProcessHeap(), 0, pdb->env_db->environ );
|
||||||
if ((ret = HeapAlloc( pdb->heap, 0, size * sizeof(WCHAR) )) != NULL)
|
if ((ret = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )) != NULL)
|
||||||
{
|
{
|
||||||
LPSTR pA = pdb->env_db->environ;
|
LPSTR pA = pdb->env_db->environ;
|
||||||
LPWSTR pW = ret;
|
LPWSTR pW = ret;
|
||||||
|
@ -323,13 +324,13 @@ BOOL WINAPI SetEnvironmentVariableA( LPCSTR name, LPCSTR value )
|
||||||
|
|
||||||
len = value ? strlen(name) + strlen(value) + 2 : 0;
|
len = value ? strlen(name) + strlen(value) + 2 : 0;
|
||||||
if (*p) len -= strlen(p) + 1; /* The name already exists */
|
if (*p) len -= strlen(p) + 1; /* The name already exists */
|
||||||
old_size = HeapSize( pdb->heap, 0, env );
|
old_size = HeapSize( GetProcessHeap(), 0, env );
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
{
|
||||||
LPSTR next = p + strlen(p) + 1; /* We know there is a next one */
|
LPSTR next = p + strlen(p) + 1; /* We know there is a next one */
|
||||||
memmove( next + len, next, old_size - (next - env) );
|
memmove( next + len, next, old_size - (next - env) );
|
||||||
}
|
}
|
||||||
if (!(new_env = HeapReAlloc( pdb->heap, 0, env, old_size + len )))
|
if (!(new_env = HeapReAlloc( GetProcessHeap(), 0, env, old_size + len )))
|
||||||
goto done;
|
goto done;
|
||||||
if (pdb->env_db->env_sel)
|
if (pdb->env_db->env_sel)
|
||||||
SELECTOR_MoveBlock( pdb->env_db->env_sel, new_env );
|
SELECTOR_MoveBlock( pdb->env_db->env_sel, new_env );
|
||||||
|
|
|
@ -206,7 +206,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
|
||||||
size = (size + 0x1f) & ~0x1f;
|
size = (size + 0x1f) & ~0x1f;
|
||||||
|
|
||||||
/* Allocate the linear memory */
|
/* Allocate the linear memory */
|
||||||
ptr = HeapAlloc( SystemHeap, 0, size );
|
ptr = HeapAlloc( GetProcessHeap(), 0, size );
|
||||||
/* FIXME: free discardable blocks and try again? */
|
/* FIXME: free discardable blocks and try again? */
|
||||||
if (!ptr) return 0;
|
if (!ptr) return 0;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
|
||||||
isCode, is32Bit, isReadOnly, &shmdata);
|
isCode, is32Bit, isReadOnly, &shmdata);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
HeapFree( SystemHeap, 0, ptr );
|
HeapFree( GetProcessHeap(), 0, ptr );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
|
||||||
if (!(pArena->flags & GA_MOVEABLE) ||
|
if (!(pArena->flags & GA_MOVEABLE) ||
|
||||||
!(pArena->flags & GA_DISCARDABLE) ||
|
!(pArena->flags & GA_DISCARDABLE) ||
|
||||||
(pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
|
(pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
|
||||||
HeapFree( SystemHeap, 0, (void *)pArena->base );
|
HeapFree( GetProcessHeap(), 0, (void *)pArena->base );
|
||||||
pArena->base = 0;
|
pArena->base = 0;
|
||||||
|
|
||||||
/* Note: we rely on the fact that SELECTOR_ReallocBlock won't
|
/* Note: we rely on the fact that SELECTOR_ReallocBlock won't
|
||||||
|
@ -314,7 +314,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
|
||||||
((char *)ptr <= DOSMEM_MemoryBase(0) + 0x100000))
|
((char *)ptr <= DOSMEM_MemoryBase(0) + 0x100000))
|
||||||
ptr = DOSMEM_ResizeBlock(0, ptr, size, NULL);
|
ptr = DOSMEM_ResizeBlock(0, ptr, size, NULL);
|
||||||
else
|
else
|
||||||
ptr = HeapReAlloc( SystemHeap, 0, ptr, size );
|
ptr = HeapReAlloc( GetProcessHeap(), 0, ptr, size );
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
SELECTOR_FreeBlock( sel, (oldsize + 0xffff) / 0x10000 );
|
SELECTOR_FreeBlock( sel, (oldsize + 0xffff) / 0x10000 );
|
||||||
|
@ -327,7 +327,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
|
||||||
sel = SELECTOR_ReallocBlock( sel, ptr, size );
|
sel = SELECTOR_ReallocBlock( sel, ptr, size );
|
||||||
if (!sel)
|
if (!sel)
|
||||||
{
|
{
|
||||||
HeapFree( SystemHeap, 0, ptr );
|
HeapFree( GetProcessHeap(), 0, ptr );
|
||||||
memset( pArena, 0, sizeof(GLOBALARENA) );
|
memset( pArena, 0, sizeof(GLOBALARENA) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
|
||||||
|
|
||||||
if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
|
if (!(pNewArena = GLOBAL_GetArena( sel, selcount )))
|
||||||
{
|
{
|
||||||
HeapFree( SystemHeap, 0, ptr );
|
HeapFree( GetProcessHeap(), 0, ptr );
|
||||||
SELECTOR_FreeBlock( sel, selcount );
|
SELECTOR_FreeBlock( sel, selcount );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,7 @@ HGLOBAL16 WINAPI GlobalFree16(
|
||||||
|
|
||||||
TRACE("%04x\n", handle );
|
TRACE("%04x\n", handle );
|
||||||
if (!GLOBAL_FreeBlock( handle )) return handle; /* failed */
|
if (!GLOBAL_FreeBlock( handle )) return handle; /* failed */
|
||||||
if (ptr) HeapFree( SystemHeap, 0, ptr );
|
if (ptr) HeapFree( GetProcessHeap(), 0, ptr );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
146
memory/heap.c
146
memory/heap.c
|
@ -93,6 +93,7 @@ typedef struct tagHEAP
|
||||||
CRITICAL_SECTION critSection; /* Critical section for serialization */
|
CRITICAL_SECTION critSection; /* Critical section for serialization */
|
||||||
DWORD flags; /* Heap flags */
|
DWORD flags; /* Heap flags */
|
||||||
DWORD magic; /* Magic number */
|
DWORD magic; /* Magic number */
|
||||||
|
void *private; /* Private pointer for the user of the heap */
|
||||||
} HEAP;
|
} HEAP;
|
||||||
|
|
||||||
#define HEAP_MAGIC ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
|
#define HEAP_MAGIC ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
|
||||||
|
@ -103,6 +104,14 @@ typedef struct tagHEAP
|
||||||
HANDLE SystemHeap = 0;
|
HANDLE SystemHeap = 0;
|
||||||
HANDLE SegptrHeap = 0;
|
HANDLE SegptrHeap = 0;
|
||||||
|
|
||||||
|
SYSTEM_HEAP_DESCR *SystemHeapDescr = 0;
|
||||||
|
|
||||||
|
static HEAP *processHeap; /* main process heap */
|
||||||
|
static HEAP *firstHeap; /* head of secondary heaps list */
|
||||||
|
|
||||||
|
/* address where we try to map the system heap */
|
||||||
|
#define SYSTEM_HEAP_BASE ((void*)0x65430000)
|
||||||
|
|
||||||
static BOOL HEAP_IsRealArena( HANDLE heap, DWORD flags, LPCVOID block, BOOL quiet );
|
static BOOL HEAP_IsRealArena( HANDLE heap, DWORD flags, LPCVOID block, BOOL quiet );
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -419,7 +428,7 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
|
||||||
|
|
||||||
/* Decommit the end of the heap */
|
/* Decommit the end of the heap */
|
||||||
|
|
||||||
HEAP_Decommit( subheap, pFree + 1 );
|
if (!(subheap->heap->flags & HEAP_WINE_SHARED)) HEAP_Decommit( subheap, pFree + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -458,6 +467,8 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
|
||||||
|
|
||||||
/* Commit memory */
|
/* Commit memory */
|
||||||
|
|
||||||
|
if (flags & HEAP_WINE_SHARED)
|
||||||
|
commitSize = totalSize; /* always commit everything in a shared heap */
|
||||||
if (!VirtualAlloc(address, commitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
|
if (!VirtualAlloc(address, commitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
|
||||||
{
|
{
|
||||||
WARN("Could not commit %08lx bytes for sub-heap %08lx\n",
|
WARN("Could not commit %08lx bytes for sub-heap %08lx\n",
|
||||||
|
@ -1001,6 +1012,20 @@ HANDLE WINAPI HeapCreate(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* link it into the per-process heap list */
|
||||||
|
if (processHeap)
|
||||||
|
{
|
||||||
|
HEAP *heapPtr = subheap->heap;
|
||||||
|
EnterCriticalSection( &processHeap->critSection );
|
||||||
|
heapPtr->next = firstHeap;
|
||||||
|
firstHeap = heapPtr;
|
||||||
|
LeaveCriticalSection( &processHeap->critSection );
|
||||||
|
}
|
||||||
|
else /* assume the first heap we create is the process main heap */
|
||||||
|
{
|
||||||
|
processHeap = subheap->heap;
|
||||||
|
}
|
||||||
|
|
||||||
return (HANDLE)subheap;
|
return (HANDLE)subheap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1010,15 +1035,29 @@ HANDLE WINAPI HeapCreate(
|
||||||
* TRUE: Success
|
* TRUE: Success
|
||||||
* FALSE: Failure
|
* FALSE: Failure
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI HeapDestroy(
|
BOOL WINAPI HeapDestroy( HANDLE heap /* [in] Handle of heap */ )
|
||||||
HANDLE heap /* [in] Handle of heap */
|
{
|
||||||
) {
|
|
||||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
HEAP *heapPtr = HEAP_GetPtr( heap );
|
||||||
SUBHEAP *subheap;
|
SUBHEAP *subheap;
|
||||||
|
|
||||||
TRACE("%08x\n", heap );
|
TRACE("%08x\n", heap );
|
||||||
if (!heapPtr) return FALSE;
|
if (!heapPtr) return FALSE;
|
||||||
|
|
||||||
|
if (heapPtr == processHeap) /* cannot delete the main process heap */
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else /* remove it from the per-process list */
|
||||||
|
{
|
||||||
|
HEAP **pptr;
|
||||||
|
EnterCriticalSection( &processHeap->critSection );
|
||||||
|
pptr = &firstHeap;
|
||||||
|
while (*pptr && *pptr != heapPtr) pptr = &(*pptr)->next;
|
||||||
|
if (*pptr) *pptr = (*pptr)->next;
|
||||||
|
LeaveCriticalSection( &processHeap->critSection );
|
||||||
|
}
|
||||||
|
|
||||||
DeleteCriticalSection( &heapPtr->critSection );
|
DeleteCriticalSection( &heapPtr->critSection );
|
||||||
subheap = &heapPtr->subheap;
|
subheap = &heapPtr->subheap;
|
||||||
while (subheap)
|
while (subheap)
|
||||||
|
@ -1390,6 +1429,105 @@ BOOL WINAPI HeapWalk(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* HEAP_CreateSystemHeap
|
||||||
|
*
|
||||||
|
* Create the system heap.
|
||||||
|
*/
|
||||||
|
BOOL HEAP_CreateSystemHeap(void)
|
||||||
|
{
|
||||||
|
SYSTEM_HEAP_DESCR *descr;
|
||||||
|
HANDLE heap;
|
||||||
|
HEAP *heapPtr;
|
||||||
|
int created;
|
||||||
|
|
||||||
|
HANDLE map = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE,
|
||||||
|
0, HEAP_DEF_SIZE, "__SystemHeap" );
|
||||||
|
if (!map) return FALSE;
|
||||||
|
created = (GetLastError() != ERROR_ALREADY_EXISTS);
|
||||||
|
|
||||||
|
if (!(heapPtr = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, SYSTEM_HEAP_BASE )))
|
||||||
|
{
|
||||||
|
/* pre-defined address not available, use any one */
|
||||||
|
fprintf( stderr, "Warning: system heap base address %p not available\n",
|
||||||
|
SYSTEM_HEAP_BASE );
|
||||||
|
if (!(heapPtr = MapViewOfFile( map, FILE_MAP_ALL_ACCESS, 0, 0, 0 )))
|
||||||
|
{
|
||||||
|
CloseHandle( map );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
heap = (HANDLE)heapPtr;
|
||||||
|
|
||||||
|
if (created) /* newly created heap */
|
||||||
|
{
|
||||||
|
HEAP_InitSubHeap( heapPtr, heapPtr, HEAP_WINE_SHARED, 0, HEAP_DEF_SIZE );
|
||||||
|
HeapLock( heap );
|
||||||
|
descr = heapPtr->private = HeapAlloc( heap, HEAP_ZERO_MEMORY, sizeof(*descr) );
|
||||||
|
assert( descr );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* wait for the heap to be initialized */
|
||||||
|
while (!heapPtr->private) Sleep(1);
|
||||||
|
HeapLock( heap );
|
||||||
|
/* remap it to the right address if necessary */
|
||||||
|
if (heapPtr->subheap.heap != heapPtr)
|
||||||
|
{
|
||||||
|
void *base = heapPtr->subheap.heap;
|
||||||
|
HeapUnlock( heap );
|
||||||
|
UnmapViewOfFile( heapPtr );
|
||||||
|
if (!(heapPtr = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, base )))
|
||||||
|
{
|
||||||
|
fprintf( stderr, "Couldn't map system heap at the correct address (%p)\n", base );
|
||||||
|
CloseHandle( map );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
heap = (HANDLE)heapPtr;
|
||||||
|
HeapLock( heap );
|
||||||
|
}
|
||||||
|
descr = heapPtr->private;
|
||||||
|
assert( descr );
|
||||||
|
}
|
||||||
|
SystemHeap = heap;
|
||||||
|
SystemHeapDescr = descr;
|
||||||
|
HeapUnlock( heap );
|
||||||
|
CloseHandle( map );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetProcessHeap (KERNEL32.259)
|
||||||
|
*/
|
||||||
|
HANDLE WINAPI GetProcessHeap(void)
|
||||||
|
{
|
||||||
|
return (HANDLE)processHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetProcessHeaps (KERNEL32.376)
|
||||||
|
*/
|
||||||
|
DWORD WINAPI GetProcessHeaps( DWORD count, HANDLE *heaps )
|
||||||
|
{
|
||||||
|
DWORD total;
|
||||||
|
HEAP *ptr;
|
||||||
|
|
||||||
|
if (!processHeap) return 0; /* should never happen */
|
||||||
|
total = 1; /* main heap */
|
||||||
|
EnterCriticalSection( &processHeap->critSection );
|
||||||
|
for (ptr = firstHeap; ptr; ptr = ptr->next) total++;
|
||||||
|
if (total <= count)
|
||||||
|
{
|
||||||
|
*heaps++ = (HANDLE)processHeap;
|
||||||
|
for (ptr = firstHeap; ptr; ptr = ptr->next) *heaps++ = (HANDLE)ptr;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection( &processHeap->critSection );
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* HEAP_xalloc
|
* HEAP_xalloc
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue