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:
Alexandre Julliard 2000-11-30 01:19:51 +00:00
parent e8e7d1eca5
commit 71d68bbae0
10 changed files with 90 additions and 120 deletions

View File

@ -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 );
}
/****************************************************************************

View File

@ -4,7 +4,6 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = msvfw32
ALTNAMES = msvideo
IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o

View File

@ -4,7 +4,6 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = oleaut32
ALTNAMES = ole2disp typelib
IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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 );
}

View File

@ -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)
*/

View File

@ -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( &current_process.crit_section );