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.
diff --git a/dlls/kernel/utthunk.c b/dlls/kernel/utthunk.c
index bbbb3fc..a4ff965 100644
--- a/dlls/kernel/utthunk.c
+++ b/dlls/kernel/utthunk.c
@@ -156,7 +156,7 @@
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 @@
break;
}
- HeapFree( SegptrHeap, 0, ut );
+ HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR, ut );
}
/****************************************************************************
diff --git a/dlls/msvideo/Makefile.in b/dlls/msvideo/Makefile.in
index 313285c..988f8fb 100644
--- a/dlls/msvideo/Makefile.in
+++ b/dlls/msvideo/Makefile.in
@@ -4,7 +4,6 @@
VPATH = @srcdir@
MODULE = msvfw32
ALTNAMES = msvideo
-IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
diff --git a/dlls/oleaut32/Makefile.in b/dlls/oleaut32/Makefile.in
index 09834f1..3f815a8 100644
--- a/dlls/oleaut32/Makefile.in
+++ b/dlls/oleaut32/Makefile.in
@@ -4,7 +4,6 @@
VPATH = @srcdir@
MODULE = oleaut32
ALTNAMES = ole2disp typelib
-IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index 945856d..bf595ae 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -98,7 +98,7 @@
&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;
diff --git a/if1632/thunk.c b/if1632/thunk.c
index fff50f7..2ef9d4a 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -123,7 +123,7 @@
|| 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;
diff --git a/include/heap.h b/include/heap.h
index 55177c8..625d586 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -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 */
diff --git a/include/winbase.h b/include/winbase.h
index e4a7a6e..31a4738 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1883,7 +1883,7 @@
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);
diff --git a/memory/heap.c b/memory/heap.c
index f8a75e9..3ba70eb 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -105,17 +105,17 @@
#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 @@
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 );
@@ -835,39 +835,6 @@
/***********************************************************************
- * 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
*
* Transform a linear pointer into a SEGPTR. The pointer must have been
@@ -877,7 +844,7 @@
{
HEAP *heapPtr = HEAP_GetPtr( heap );
SUBHEAP *subheap;
- SEGPTR ret;
+ SEGPTR ret = 0;
/* Validate the parameters */
@@ -893,22 +860,61 @@
/* 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 @@
* 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 @@
{
/* 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 @@
}
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 @@
/* 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 @@
/* 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 @@
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 @@
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 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 @@
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 );
}
diff --git a/memory/selector.c b/memory/selector.c
index 7f48f83..d5d8df0 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -552,33 +552,6 @@
}
/***********************************************************************
- * 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)
*/
BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldtent)
diff --git a/scheduler/process.c b/scheduler/process.c
index 63979e0..5f61c8e 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -217,9 +217,6 @@
/* 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 );