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