Use the HEAP_WINE_SEGPTR flag to specify allocations on the segptr heap.
Added a hack in MapLS to recognize such allocations and use the heap selector in this case.
This commit is contained in:
parent
e8e7d1eca5
commit
71d68bbae0
|
@ -156,7 +156,7 @@ static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
|
|||
if ( !UTGlue16_Segptr ) return NULL;
|
||||
}
|
||||
|
||||
ut = HeapAlloc( SegptrHeap, HEAP_ZERO_MEMORY, sizeof(UTINFO) );
|
||||
ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_WINE_SEGPTR, sizeof(UTINFO) );
|
||||
if ( !ut ) return NULL;
|
||||
|
||||
ut->hModule = hModule;
|
||||
|
@ -196,7 +196,7 @@ static void UTFree( UTINFO *ut )
|
|||
break;
|
||||
}
|
||||
|
||||
HeapFree( SegptrHeap, 0, ut );
|
||||
HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR, ut );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -4,7 +4,6 @@ SRCDIR = @srcdir@
|
|||
VPATH = @srcdir@
|
||||
MODULE = msvfw32
|
||||
ALTNAMES = msvideo
|
||||
IMPORTS = ntdll
|
||||
|
||||
LDDLLFLAGS = @LDDLLFLAGS@
|
||||
SYMBOLFILE = $(MODULE).tmp.o
|
||||
|
|
|
@ -4,7 +4,6 @@ SRCDIR = @srcdir@
|
|||
VPATH = @srcdir@
|
||||
MODULE = oleaut32
|
||||
ALTNAMES = ole2disp typelib
|
||||
IMPORTS = ntdll
|
||||
|
||||
LDDLLFLAGS = @LDDLLFLAGS@
|
||||
SYMBOLFILE = $(MODULE).tmp.o
|
||||
|
|
|
@ -98,7 +98,7 @@ HFONT WIN16DRV_FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font)
|
|||
&physDev->lf, 0, 0);
|
||||
|
||||
if( physDev->FontInfo &&
|
||||
HeapSize( SegptrHeap, 0, physDev->FontInfo ) < nSize )
|
||||
HeapSize( GetProcessHeap(), HEAP_WINE_SEGPTR, physDev->FontInfo ) < nSize )
|
||||
{
|
||||
SEGPTR_FREE( physDev->FontInfo );
|
||||
physDev->FontInfo = NULL;
|
||||
|
|
|
@ -123,7 +123,7 @@ void THUNK_Free( FARPROC thunk )
|
|||
|| t->magic != CALLTO16_THUNK_MAGIC )
|
||||
return;
|
||||
|
||||
if (HEAP_IsInsideHeap( GetProcessHeap(), 0, t ))
|
||||
if (HeapValidate( GetProcessHeap(), 0, t ))
|
||||
{
|
||||
THUNK **prev = &firstThunk;
|
||||
while (*prev && (*prev != t)) prev = &(*prev)->next;
|
||||
|
|
|
@ -15,29 +15,23 @@
|
|||
#include "wine/windef16.h" /* for SEGPTR */
|
||||
|
||||
extern HANDLE SystemHeap;
|
||||
extern HANDLE SegptrHeap;
|
||||
|
||||
extern int HEAP_IsInsideHeap( HANDLE heap, DWORD flags, LPCVOID ptr );
|
||||
extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr );
|
||||
extern BOOL HEAP_CreateSystemHeap(void);
|
||||
|
||||
/* SEGPTR helper macros */
|
||||
|
||||
#define SEGPTR_ALLOC(size) \
|
||||
(HeapAlloc( SegptrHeap, 0, (size) ))
|
||||
(HeapAlloc( GetProcessHeap(), HEAP_WINE_SEGPTR, (size) ))
|
||||
#define SEGPTR_NEW(type) \
|
||||
((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) ))
|
||||
((type *)HeapAlloc( GetProcessHeap(), HEAP_WINE_SEGPTR, sizeof(type) ))
|
||||
#define SEGPTR_STRDUP(str) \
|
||||
(HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
|
||||
(HIWORD(str) ? HEAP_strdupA( GetProcessHeap(), HEAP_WINE_SEGPTR, (str) ) : (LPSTR)(str))
|
||||
#define SEGPTR_STRDUP_WtoA(str) \
|
||||
(HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
|
||||
/* define an inline function, a macro won't do */
|
||||
static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) {
|
||||
return (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, ptr ) : (SEGPTR)ptr);
|
||||
}
|
||||
#define SEGPTR_GET(ptr) SEGPTR_Get(ptr)
|
||||
(HIWORD(str) ? HEAP_strdupWtoA( GetProcessHeap(), HEAP_WINE_SEGPTR, (str) ) : (LPSTR)(str))
|
||||
#define SEGPTR_FREE(ptr) \
|
||||
(HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0)
|
||||
(HIWORD(ptr) ? HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR, (ptr) ) : 0)
|
||||
#define SEGPTR_GET(ptr) MapLS(ptr)
|
||||
|
||||
|
||||
/* strdup macros */
|
||||
|
|
|
@ -1883,7 +1883,7 @@ typedef struct tagSYSLEVEL
|
|||
void WINAPI DisposeLZ32Handle(HANDLE);
|
||||
HANDLE WINAPI DosFileHandleToWin32Handle(HFILE);
|
||||
VOID WINAPI GetpWin16Lock(SYSLEVEL**);
|
||||
DWORD WINAPI MapLS(LPVOID);
|
||||
DWORD WINAPI MapLS(LPCVOID);
|
||||
LPVOID WINAPI MapSL(DWORD);
|
||||
VOID WINAPI ReleaseThunkLock(DWORD*);
|
||||
VOID WINAPI RestoreThunkLock(DWORD);
|
||||
|
|
150
memory/heap.c
150
memory/heap.c
|
@ -105,17 +105,17 @@ typedef struct tagHEAP
|
|||
#define COMMIT_MASK 0xffff /* bitmask for commit/decommit granularity */
|
||||
|
||||
HANDLE SystemHeap = 0;
|
||||
HANDLE SegptrHeap = 0;
|
||||
|
||||
SYSTEM_HEAP_DESCR *SystemHeapDescr = 0;
|
||||
|
||||
static HEAP *processHeap; /* main process heap */
|
||||
static HEAP *segptrHeap; /* main segptr 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( HEAP *heapPtr, DWORD flags, LPCVOID block, BOOL quiet );
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GET_EIP() (__builtin_return_address(0))
|
||||
|
@ -220,7 +220,7 @@ static HEAP *HEAP_GetPtr(
|
|||
SetLastError( ERROR_INVALID_HANDLE );
|
||||
return NULL;
|
||||
}
|
||||
if (TRACE_ON(heap) && !HEAP_IsRealArena( heap, 0, NULL, NOISY ))
|
||||
if (TRACE_ON(heap) && !HEAP_IsRealArena( heapPtr, 0, NULL, NOISY ))
|
||||
{
|
||||
HEAP_Dump( heapPtr );
|
||||
assert( FALSE );
|
||||
|
@ -834,39 +834,6 @@ static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena, BOOL
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HEAP_IsInsideHeap
|
||||
* Checks whether the pointer points to a block inside a given heap.
|
||||
*
|
||||
* NOTES
|
||||
* Should this return BOOL32?
|
||||
*
|
||||
* RETURNS
|
||||
* !0: Success
|
||||
* 0: Failure
|
||||
*/
|
||||
int HEAP_IsInsideHeap(
|
||||
HANDLE heap, /* [in] Heap */
|
||||
DWORD flags, /* [in] Flags */
|
||||
LPCVOID ptr /* [in] Pointer */
|
||||
) {
|
||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
||||
SUBHEAP *subheap;
|
||||
int ret;
|
||||
|
||||
/* Validate the parameters */
|
||||
|
||||
if (!heapPtr) return 0;
|
||||
flags |= heapPtr->flags;
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
|
||||
ret = (((subheap = HEAP_FindSubHeap( heapPtr, ptr )) != NULL) &&
|
||||
(((char *)ptr >= (char *)subheap + subheap->headerSize
|
||||
+ sizeof(ARENA_INUSE))));
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HEAP_GetSegptr
|
||||
*
|
||||
|
@ -877,7 +844,7 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
|
|||
{
|
||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
||||
SUBHEAP *subheap;
|
||||
SEGPTR ret;
|
||||
SEGPTR ret = 0;
|
||||
|
||||
/* Validate the parameters */
|
||||
|
||||
|
@ -893,21 +860,60 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
|
|||
|
||||
/* Get the subheap */
|
||||
|
||||
if (!(subheap = HEAP_FindSubHeap( heapPtr, ptr )))
|
||||
{
|
||||
ERR("%p is not inside heap %08x\n",
|
||||
ptr, heap );
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
|
||||
return 0;
|
||||
}
|
||||
if ((subheap = HEAP_FindSubHeap( heapPtr, ptr )))
|
||||
ret = PTR_SEG_OFF_TO_SEGPTR(subheap->selector, (char *)ptr - (char *)subheap);
|
||||
|
||||
/* Build the SEGPTR */
|
||||
|
||||
ret = PTR_SEG_OFF_TO_SEGPTR(subheap->selector, (DWORD)ptr-(DWORD)subheap);
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MapLS (KERNEL32.522)
|
||||
*
|
||||
* Maps linear pointer to segmented.
|
||||
*/
|
||||
SEGPTR WINAPI MapLS( LPCVOID ptr )
|
||||
{
|
||||
SUBHEAP *subheap;
|
||||
SEGPTR ret = 0;
|
||||
|
||||
if (!HIWORD(ptr)) return (SEGPTR)ptr;
|
||||
|
||||
/* check if the pointer is inside the segptr heap */
|
||||
EnterCriticalSection( &segptrHeap->critSection );
|
||||
if ((subheap = HEAP_FindSubHeap( segptrHeap, ptr )))
|
||||
ret = PTR_SEG_OFF_TO_SEGPTR( subheap->selector, (char *)ptr - (char *)subheap );
|
||||
LeaveCriticalSection( &segptrHeap->critSection );
|
||||
|
||||
/* otherwise, allocate a brand-new selector */
|
||||
if (!ret)
|
||||
{
|
||||
WORD sel = SELECTOR_AllocBlock( ptr, 0x10000, WINE_LDT_FLAGS_DATA );
|
||||
ret = PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* UnMapLS (KERNEL32.700)
|
||||
*
|
||||
* Free mapped selector.
|
||||
*/
|
||||
void WINAPI UnMapLS( SEGPTR sptr )
|
||||
{
|
||||
SUBHEAP *subheap;
|
||||
if (!SELECTOROF(sptr)) return;
|
||||
|
||||
/* check if ptr is inside segptr heap */
|
||||
EnterCriticalSection( &segptrHeap->critSection );
|
||||
subheap = HEAP_FindSubHeap( segptrHeap, PTR_SEG_TO_LIN(sptr) );
|
||||
if (subheap->selector != SELECTOROF(sptr)) subheap = NULL;
|
||||
LeaveCriticalSection( &segptrHeap->critSection );
|
||||
/* if not inside heap, free the selector */
|
||||
if (!subheap) FreeSelector16( SELECTOROF(sptr) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* HEAP_IsRealArena [Internal]
|
||||
* Validates a block is a valid arena.
|
||||
|
@ -916,20 +922,18 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
|
|||
* TRUE: Success
|
||||
* FALSE: Failure
|
||||
*/
|
||||
static BOOL HEAP_IsRealArena(
|
||||
HANDLE heap, /* [in] Handle to the heap */
|
||||
static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
|
||||
DWORD flags, /* [in] Bit flags that control access during operation */
|
||||
LPCVOID block, /* [in] Optional pointer to memory block to validate */
|
||||
BOOL quiet /* [in] Flag - if true, HEAP_ValidateInUseArena
|
||||
BOOL quiet ) /* [in] Flag - if true, HEAP_ValidateInUseArena
|
||||
* does not complain */
|
||||
) {
|
||||
{
|
||||
SUBHEAP *subheap;
|
||||
HEAP *heapPtr = (HEAP *)(heap);
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
|
||||
{
|
||||
ERR("Invalid heap %08x!\n", heap );
|
||||
ERR("Invalid heap %p!\n", heapPtr );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -943,18 +947,14 @@ static BOOL HEAP_IsRealArena(
|
|||
{
|
||||
/* Only check this single memory block */
|
||||
|
||||
/* The following code is really HEAP_IsInsideHeap *
|
||||
* with serialization already done. */
|
||||
if (!(subheap = HEAP_FindSubHeap( heapPtr, block )) ||
|
||||
((char *)block < (char *)subheap + subheap->headerSize
|
||||
+ sizeof(ARENA_INUSE)))
|
||||
{
|
||||
if (quiet == NOISY)
|
||||
ERR("Heap %08lx: block %08lx is not inside heap\n",
|
||||
(DWORD)heap, (DWORD)block );
|
||||
ERR("Heap %p: block %p is not inside heap\n", heapPtr, block );
|
||||
else if (WARN_ON(heap))
|
||||
WARN("Heap %08lx: block %08lx is not inside heap\n",
|
||||
(DWORD)heap, (DWORD)block );
|
||||
WARN("Heap %p: block %p is not inside heap\n", heapPtr, block );
|
||||
ret = FALSE;
|
||||
} else
|
||||
ret = HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)block - 1, quiet );
|
||||
|
@ -1038,9 +1038,16 @@ HANDLE WINAPI HeapCreate(
|
|||
}
|
||||
else /* assume the first heap we create is the process main heap */
|
||||
{
|
||||
SUBHEAP *segptr;
|
||||
processHeap = subheap->heap;
|
||||
/* create the SEGPTR heap */
|
||||
if (!(segptr = HEAP_CreateSubHeap( NULL, flags|HEAP_WINE_SEGPTR|HEAP_GROWABLE, 0, 0 )))
|
||||
{
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
return 0;
|
||||
}
|
||||
segptrHeap = segptr->heap;
|
||||
}
|
||||
|
||||
return (HANDLE)subheap;
|
||||
}
|
||||
|
||||
|
@ -1109,6 +1116,7 @@ LPVOID WINAPI HeapAlloc(
|
|||
|
||||
/* Validate the parameters */
|
||||
|
||||
if ((flags & HEAP_WINE_SEGPTR) && size < 0x10000) heapPtr = segptrHeap;
|
||||
if (!heapPtr) return NULL;
|
||||
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
|
||||
flags |= heapPtr->flags;
|
||||
|
@ -1178,18 +1186,14 @@ BOOL WINAPI HeapFree(
|
|||
|
||||
/* Validate the parameters */
|
||||
|
||||
if (!ptr) return TRUE; /* freeing a NULL ptr is doesn't indicate an error in Win2k */
|
||||
if (flags & HEAP_WINE_SEGPTR) heapPtr = segptrHeap;
|
||||
if (!heapPtr) return FALSE;
|
||||
if (!ptr) /* Freeing a NULL ptr is doesn't indicate an error in Win2k */
|
||||
{
|
||||
WARN("(%08x,%08lx,%08lx): asked to free NULL\n",
|
||||
heap, flags, (DWORD)ptr );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
flags &= HEAP_NO_SERIALIZE;
|
||||
flags |= heapPtr->flags;
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
|
||||
if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET ))
|
||||
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
|
||||
{
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
|
@ -1230,6 +1234,7 @@ LPVOID WINAPI HeapReAlloc(
|
|||
SUBHEAP *subheap;
|
||||
|
||||
if (!ptr) return HeapAlloc( heap, flags, size ); /* FIXME: correct? */
|
||||
if ((flags & HEAP_WINE_SEGPTR) && size < 0x10000) heapPtr = segptrHeap;
|
||||
if (!(heapPtr = HEAP_GetPtr( heap ))) return FALSE;
|
||||
|
||||
/* Validate the parameters */
|
||||
|
@ -1241,7 +1246,7 @@ LPVOID WINAPI HeapReAlloc(
|
|||
if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE;
|
||||
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
|
||||
if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET ))
|
||||
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
|
||||
{
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
|
@ -1395,11 +1400,12 @@ DWORD WINAPI HeapSize(
|
|||
DWORD ret;
|
||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
||||
|
||||
if (flags & HEAP_WINE_SEGPTR) heapPtr = segptrHeap;
|
||||
if (!heapPtr) return FALSE;
|
||||
flags &= HEAP_NO_SERIALIZE;
|
||||
flags |= heapPtr->flags;
|
||||
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
|
||||
if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET ))
|
||||
if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
ret = 0xffffffff;
|
||||
|
@ -1433,8 +1439,10 @@ BOOL WINAPI HeapValidate(
|
|||
DWORD flags, /* [in] Bit flags that control access during operation */
|
||||
LPCVOID block /* [in] Optional pointer to memory block to validate */
|
||||
) {
|
||||
|
||||
return HEAP_IsRealArena( heap, flags, block, QUIET );
|
||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
||||
if (flags & HEAP_WINE_SEGPTR) heapPtr = segptrHeap;
|
||||
if (!heapPtr) return FALSE;
|
||||
return HEAP_IsRealArena( heapPtr, flags, block, QUIET );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -551,33 +551,6 @@ void WINAPI UnMapSLFixArray( SEGPTR sptr[], INT length, CONTEXT86 *context )
|
|||
/* Must not change EAX, hence defined as 'register' function */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MapLS (KERNEL32.522)
|
||||
*
|
||||
* Maps linear pointer to segmented.
|
||||
*/
|
||||
SEGPTR WINAPI MapLS( LPVOID ptr )
|
||||
{
|
||||
if (!HIWORD(ptr))
|
||||
return (SEGPTR)ptr;
|
||||
else
|
||||
{
|
||||
WORD sel = SELECTOR_AllocBlock( ptr, 0x10000, WINE_LDT_FLAGS_DATA );
|
||||
return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* UnMapLS (KERNEL32.700)
|
||||
*
|
||||
* Free mapped selector.
|
||||
*/
|
||||
void WINAPI UnMapLS( SEGPTR sptr )
|
||||
{
|
||||
if (SELECTOROF(sptr)) FreeSelector16( SELECTOROF(sptr) );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetThreadSelectorEntry (KERNEL32)
|
||||
*/
|
||||
|
|
|
@ -217,9 +217,6 @@ static BOOL process_init( char *argv[] )
|
|||
/* Copy the parent environment */
|
||||
if (!ENV_BuildEnvironment()) return FALSE;
|
||||
|
||||
/* Create the SEGPTR heap */
|
||||
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
|
||||
|
||||
/* Initialize the critical sections */
|
||||
InitializeCriticalSection( ¤t_process.crit_section );
|
||||
|
||||
|
|
Loading…
Reference in New Issue