kernel32: Make toolhelp.dll into a stand-alone 16-bit module.
diff --git a/.gitignore b/.gitignore
index 45362c3..063b358 100644
--- a/.gitignore
+++ b/.gitignore
@@ -119,7 +119,6 @@
 dlls/shdocvw/shdocvw_v1.tlb
 dlls/stdole2.tlb/std_ole_v2.tlb
 dlls/stdole32.tlb/std_ole_v1.tlb
-dlls/toolhelp.dll16
 dlls/user.exe16
 dlls/ver.dll16
 dlls/wineps16.drv16
diff --git a/configure b/configure
index b2cbd87..76d1fda 100755
--- a/configure
+++ b/configure
@@ -16682,6 +16682,14 @@
 ac_config_files="$ac_config_files dlls/tapi32/Makefile"
 
 ALL_MAKEFILES="$ALL_MAKEFILES \\
+	dlls/toolhelp.dll16/Makefile"
+test "x$enable_win16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\
+	toolhelp.dll16"
+ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS
+dlls/toolhelp.dll16/Makefile: dlls/toolhelp.dll16/Makefile.in dlls/Makedll.rules"
+ac_config_files="$ac_config_files dlls/toolhelp.dll16/Makefile"
+
+ALL_MAKEFILES="$ALL_MAKEFILES \\
 	dlls/traffic/Makefile"
 test "x$enable_traffic" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\
 	traffic"
@@ -19056,6 +19064,7 @@
     "dlls/system.drv16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/system.drv16/Makefile" ;;
     "dlls/t2embed/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/t2embed/Makefile" ;;
     "dlls/tapi32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/tapi32/Makefile" ;;
+    "dlls/toolhelp.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/toolhelp.dll16/Makefile" ;;
     "dlls/traffic/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/traffic/Makefile" ;;
     "dlls/twain.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/twain.dll16/Makefile" ;;
     "dlls/twain_32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/twain_32/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index 5fb8e9b..00011f4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2446,6 +2446,7 @@
 WINE_CONFIG_MAKEFILE([dlls/system.drv16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16])
 WINE_CONFIG_MAKEFILE([dlls/t2embed/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS])
 WINE_CONFIG_MAKEFILE([dlls/tapi32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS])
+WINE_CONFIG_MAKEFILE([dlls/toolhelp.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16])
 WINE_CONFIG_MAKEFILE([dlls/traffic/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS])
 WINE_CONFIG_MAKEFILE([dlls/twain.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16])
 WINE_CONFIG_MAKEFILE([dlls/twain_32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS])
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index 78be337..de9a823 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -23,7 +23,6 @@
 	krnl386.exe16 \
 	mmsystem.dll16 \
 	setupx.dll16 \
-	toolhelp.dll16 \
 	user.exe16 \
 	ver.dll16 \
 	wineps16.drv16 \
@@ -44,7 +43,7 @@
 gdi.exe16:
 	echo "gdi32.dll" >$@
 
-krnl386.exe16 toolhelp.dll16:
+krnl386.exe16:
 	echo "kernel32.dll" >$@
 
 setupx.dll16:
diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in
index a64b699..df97736 100644
--- a/dlls/kernel32/Makefile.in
+++ b/dlls/kernel32/Makefile.in
@@ -9,9 +9,7 @@
 EXTRALIBS = @COREFOUNDATIONLIB@ @LIBPOLL@
 EXTRADLLFLAGS = -Wb,-F,KERNEL32.dll -Wl,--image-base,0x7b800000
 
-SPEC_SRCS16 = \
-	krnl386.exe.spec \
-	toolhelp.spec
+SPEC_SRCS16 = krnl386.exe.spec
 
 C_SRCS = \
 	actctx.c \
@@ -71,8 +69,7 @@
 	atom16.c \
 	error16.c \
 	kernel16.c \
-	registry16.c \
-	toolhelp16.c
+	registry16.c
 
 RC_SRCS = \
 	locale_rc.rc \
diff --git a/dlls/kernel32/global16.c b/dlls/kernel32/global16.c
index e572c3d..c5dcc14 100644
--- a/dlls/kernel32/global16.c
+++ b/dlls/kernel32/global16.c
@@ -38,7 +38,6 @@
 #endif
 
 #include "wine/winbase16.h"
-#include "toolhelp.h"
 #include "winternl.h"
 #include "kernel_private.h"
 #include "kernel16_private.h"
@@ -951,6 +950,8 @@
 
 /***********************************************************************
  *           GlobalHandleToSel   (TOOLHELP.50)
+ *
+ * FIXME: This is in TOOLHELP but we keep a copy here for now.
  */
 WORD WINAPI GlobalHandleToSel16( HGLOBAL16 handle )
 {
@@ -969,100 +970,6 @@
 
 
 /***********************************************************************
- *           GlobalFirst   (TOOLHELP.51)
- */
-BOOL16 WINAPI GlobalFirst16( GLOBALENTRY *pGlobal, WORD wFlags )
-{
-    if (wFlags == GLOBAL_LRU) return FALSE;
-    pGlobal->dwNext = 0;
-    return GlobalNext16( pGlobal, wFlags );
-}
-
-
-/***********************************************************************
- *           GlobalNext   (TOOLHELP.52)
- */
-BOOL16 WINAPI GlobalNext16( GLOBALENTRY *pGlobal, WORD wFlags)
-{
-    GLOBALARENA *pArena;
-
-    if (pGlobal->dwNext >= globalArenaSize) return FALSE;
-    pArena = pGlobalArena + pGlobal->dwNext;
-    if (wFlags == GLOBAL_FREE)  /* only free blocks */
-    {
-        int i;
-        for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++)
-            if (pArena->size == 0) break;  /* block is free */
-        if (i >= globalArenaSize) return FALSE;
-        pGlobal->dwNext = i;
-    }
-
-    pGlobal->dwAddress    = (DWORD_PTR)pArena->base;
-    pGlobal->dwBlockSize  = pArena->size;
-    pGlobal->hBlock       = pArena->handle;
-    pGlobal->wcLock       = pArena->lockCount;
-    pGlobal->wcPageLock   = pArena->pageLockCount;
-    pGlobal->wFlags       = (GetCurrentPDB16() == pArena->hOwner);
-    pGlobal->wHeapPresent = FALSE;
-    pGlobal->hOwner       = pArena->hOwner;
-    pGlobal->wType        = GT_UNKNOWN;
-    pGlobal->wData        = 0;
-    pGlobal->dwNext++;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GlobalInfo   (TOOLHELP.53)
- */
-BOOL16 WINAPI GlobalInfo16( GLOBALINFO *pInfo )
-{
-    int i;
-    GLOBALARENA *pArena;
-
-    pInfo->wcItems = globalArenaSize;
-    pInfo->wcItemsFree = 0;
-    pInfo->wcItemsLRU = 0;
-    for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++)
-        if (pArena->size == 0) pInfo->wcItemsFree++;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GlobalEntryHandle   (TOOLHELP.54)
- */
-BOOL16 WINAPI GlobalEntryHandle16( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
-{
-    GLOBALARENA *pArena = GET_ARENA_PTR(hItem);
-
-    pGlobal->dwAddress    = (DWORD_PTR)pArena->base;
-    pGlobal->dwBlockSize  = pArena->size;
-    pGlobal->hBlock       = pArena->handle;
-    pGlobal->wcLock       = pArena->lockCount;
-    pGlobal->wcPageLock   = pArena->pageLockCount;
-    pGlobal->wFlags       = (GetCurrentPDB16() == pArena->hOwner);
-    pGlobal->wHeapPresent = FALSE;
-    pGlobal->hOwner       = pArena->hOwner;
-    pGlobal->wType        = GT_UNKNOWN;
-    pGlobal->wData        = 0;
-    pGlobal->dwNext++;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GlobalEntryModule   (TOOLHELP.55)
- */
-BOOL16 WINAPI GlobalEntryModule16( GLOBALENTRY *pGlobal, HMODULE16 hModule,
-                                 WORD wSeg )
-{
-    FIXME("(%p, 0x%04x, 0x%04x), stub.\n", pGlobal, hModule, wSeg);
-    return FALSE;
-}
-
-
-/***********************************************************************
  *           GetFreeMemInfo   (KERNEL.316)
  */
 DWORD WINAPI GetFreeMemInfo16(void)
diff --git a/dlls/kernel32/local16.c b/dlls/kernel32/local16.c
index 6171975..3470b31 100644
--- a/dlls/kernel32/local16.c
+++ b/dlls/kernel32/local16.c
@@ -35,7 +35,6 @@
 #include <string.h>
 #include "wine/winbase16.h"
 #include "wownt32.h"
-#include "toolhelp.h"
 #include "winternl.h"
 #include "kernel_private.h"
 #include "kernel16_private.h"
@@ -126,6 +125,30 @@
     WORD magic;                 /* 28 Magic number */
 } LOCALHEAPINFO;
 
+typedef struct
+{
+    DWORD dwSize;                /* 00 */
+    DWORD dwMemReserved;         /* 04 */
+    DWORD dwMemCommitted;        /* 08 */
+    DWORD dwTotalFree;           /* 0C */
+    DWORD dwLargestFreeBlock;    /* 10 */
+    DWORD dwcFreeHandles;        /* 14 */
+} LOCAL32INFO;
+
+typedef struct
+{
+    DWORD dwSize;                /* 00 */
+    WORD hHandle;                /* 04 */
+    DWORD dwAddress;             /* 06 */
+    DWORD dwSizeBlock;           /* 0A */
+    WORD wFlags;                 /* 0E */
+    WORD wType;                  /* 10 */
+    WORD hHeap;                  /* 12 */
+    WORD wHeapType;              /* 14 */
+    DWORD dwNext;                /* 16 */
+    DWORD dwNextAlt;             /* 1A */
+} LOCAL32ENTRY;
+
 #include "poppack.h"
 
 #define LOCAL_HEAP_MAGIC  0x484c  /* 'LH' */
@@ -1686,68 +1709,6 @@
 
 
 /***********************************************************************
- *           LocalInfo   (TOOLHELP.56)
- */
-BOOL16 WINAPI LocalInfo16( LOCALINFO *pLocalInfo, HGLOBAL16 handle )
-{
-    LOCALHEAPINFO *pInfo = LOCAL_GetHeap(SELECTOROF(WOWGlobalLock16(handle)));
-    if (!pInfo) return FALSE;
-    pLocalInfo->wcItems = pInfo->items;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           LocalFirst   (TOOLHELP.57)
- */
-BOOL16 WINAPI LocalFirst16( LOCALENTRY *pLocalEntry, HGLOBAL16 handle )
-{
-    WORD ds = GlobalHandleToSel16( handle );
-    char *ptr = MapSL( MAKESEGPTR( ds, 0 ) );
-    LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
-    if (!pInfo) return FALSE;
-
-    pLocalEntry->hHandle   = pInfo->first + ARENA_HEADER_SIZE;
-    pLocalEntry->wAddress  = pLocalEntry->hHandle;
-    pLocalEntry->wFlags    = LF_FIXED;
-    pLocalEntry->wcLock    = 0;
-    pLocalEntry->wType     = LT_NORMAL;
-    pLocalEntry->hHeap     = handle;
-    pLocalEntry->wHeapType = NORMAL_HEAP;
-    pLocalEntry->wNext     = ARENA_PTR(ptr,pInfo->first)->next;
-    pLocalEntry->wSize     = pLocalEntry->wNext - pLocalEntry->hHandle;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           LocalNext   (TOOLHELP.58)
- */
-BOOL16 WINAPI LocalNext16( LOCALENTRY *pLocalEntry )
-{
-    WORD ds = GlobalHandleToSel16( pLocalEntry->hHeap );
-    char *ptr = MapSL( MAKESEGPTR( ds, 0 ) );
-    LOCALARENA *pArena;
-
-    if (!LOCAL_GetHeap( ds )) return FALSE;
-    if (!pLocalEntry->wNext) return FALSE;
-    pArena = ARENA_PTR( ptr, pLocalEntry->wNext );
-
-    pLocalEntry->hHandle   = pLocalEntry->wNext + ARENA_HEADER_SIZE;
-    pLocalEntry->wAddress  = pLocalEntry->hHandle;
-    pLocalEntry->wFlags    = (pArena->prev & 3) + 1;
-    pLocalEntry->wcLock    = 0;
-    pLocalEntry->wType     = LT_NORMAL;
-    if (pArena->next != pLocalEntry->wNext)  /* last one? */
-        pLocalEntry->wNext = pArena->next;
-    else
-        pLocalEntry->wNext = 0;
-    pLocalEntry->wSize     = pLocalEntry->wNext - pLocalEntry->hHandle;
-    return TRUE;
-}
-
-
-/***********************************************************************
  * 32-bit local heap functions (Win95; undocumented)
  */
 
@@ -2189,7 +2150,6 @@
 
 /***********************************************************************
  *           Local32Info   (KERNEL.444)
- *           Local32Info   (TOOLHELP.84)
  */
 BOOL16 WINAPI Local32Info16( LOCAL32INFO *pLocal32Info, HGLOBAL16 handle )
 {
@@ -2236,7 +2196,6 @@
 
 /***********************************************************************
  *           Local32First   (KERNEL.445)
- *           Local32First   (TOOLHELP.85)
  */
 BOOL16 WINAPI Local32First16( LOCAL32ENTRY *pLocal32Entry, HGLOBAL16 handle )
 {
@@ -2246,7 +2205,6 @@
 
 /***********************************************************************
  *           Local32Next   (KERNEL.446)
- *           Local32Next   (TOOLHELP.86)
  */
 BOOL16 WINAPI Local32Next16( LOCAL32ENTRY *pLocal32Entry )
 {
diff --git a/dlls/kernel32/ne_module.c b/dlls/kernel32/ne_module.c
index 87a1a86..8f22ccb 100644
--- a/dlls/kernel32/ne_module.c
+++ b/dlls/kernel32/ne_module.c
@@ -36,7 +36,6 @@
 #include "wine/winbase16.h"
 #include "wownt32.h"
 #include "winternl.h"
-#include "toolhelp.h"
 #include "kernel_private.h"
 #include "kernel16_private.h"
 #include "wine/exception.h"
@@ -1955,58 +1954,6 @@
     return GetProcAddress16( LOWORD(hModule), name );
 }
 
-/**********************************************************************
- *	    ModuleFirst    (TOOLHELP.59)
- */
-BOOL16 WINAPI ModuleFirst16( MODULEENTRY *lpme )
-{
-    lpme->wNext = hFirstModule;
-    return ModuleNext16( lpme );
-}
-
-
-/**********************************************************************
- *	    ModuleNext    (TOOLHELP.60)
- */
-BOOL16 WINAPI ModuleNext16( MODULEENTRY *lpme )
-{
-    NE_MODULE *pModule;
-    char *name;
-
-    if (!lpme->wNext) return FALSE;
-    if (!(pModule = NE_GetPtr( lpme->wNext ))) return FALSE;
-    name = (char *)pModule + pModule->ne_restab;
-    memcpy( lpme->szModule, name + 1, min(*name, MAX_MODULE_NAME) );
-    lpme->szModule[min(*name, MAX_MODULE_NAME)] = '\0';
-    lpme->hModule = lpme->wNext;
-    lpme->wcUsage = pModule->count;
-    lstrcpynA( lpme->szExePath, NE_MODULE_NAME(pModule), sizeof(lpme->szExePath) );
-    lpme->wNext = pModule->next;
-    return TRUE;
-}
-
-
-/**********************************************************************
- *	    ModuleFindName    (TOOLHELP.61)
- */
-BOOL16 WINAPI ModuleFindName16( MODULEENTRY *lpme, LPCSTR name )
-{
-    lpme->wNext = GetModuleHandle16( name );
-    return ModuleNext16( lpme );
-}
-
-
-/**********************************************************************
- *	    ModuleFindHandle    (TOOLHELP.62)
- */
-BOOL16 WINAPI ModuleFindHandle16( MODULEENTRY *lpme, HMODULE16 hModule )
-{
-    hModule = GetExePtr( hModule );
-    lpme->wNext = hModule;
-    return ModuleNext16( lpme );
-}
-
-
 /***************************************************************************
  *          IsRomModule    (KERNEL.323)
  */
diff --git a/dlls/kernel32/selector.c b/dlls/kernel32/selector.c
index d505982..33e6b90 100644
--- a/dlls/kernel32/selector.c
+++ b/dlls/kernel32/selector.c
@@ -27,7 +27,6 @@
 #include "wine/server.h"
 #include "wine/debug.h"
 #include "kernel_private.h"
-#include "toolhelp.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(selector);
 
@@ -418,41 +417,6 @@
 }
 
 
-/***********************************************************************
- *           MemoryRead   (TOOLHELP.78)
- */
-DWORD WINAPI MemoryRead16( WORD sel, DWORD offset, void *buffer, DWORD count )
-{
-    LDT_ENTRY entry;
-    DWORD limit;
-
-    wine_ldt_get_entry( sel, &entry );
-    if (wine_ldt_is_empty( &entry )) return 0;
-    limit = wine_ldt_get_limit( &entry );
-    if (offset > limit) return 0;
-    if (offset + count > limit + 1) count = limit + 1 - offset;
-    memcpy( buffer, (char *)wine_ldt_get_base(&entry) + offset, count );
-    return count;
-}
-
-
-/***********************************************************************
- *           MemoryWrite   (TOOLHELP.79)
- */
-DWORD WINAPI MemoryWrite16( WORD sel, DWORD offset, void *buffer, DWORD count )
-{
-    LDT_ENTRY entry;
-    DWORD limit;
-
-    wine_ldt_get_entry( sel, &entry );
-    if (wine_ldt_is_empty( &entry )) return 0;
-    limit = wine_ldt_get_limit( &entry );
-    if (offset > limit) return 0;
-    if (offset + count > limit) count = limit + 1 - offset;
-    memcpy( (char *)wine_ldt_get_base(&entry) + offset, buffer, count );
-    return count;
-}
-
 /************************************* Win95 pointer mapping functions *
  *
  */
diff --git a/dlls/kernel32/task.c b/dlls/kernel32/task.c
index 0381097..2987420 100644
--- a/dlls/kernel32/task.c
+++ b/dlls/kernel32/task.c
@@ -38,14 +38,12 @@
 
 #include "wine/winbase16.h"
 #include "winternl.h"
-#include "toolhelp.h"
 #include "kernel_private.h"
 #include "kernel16_private.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(task);
-WINE_DECLARE_DEBUG_CHANNEL(toolhelp);
 
 #include "pshpack1.h"
 
@@ -1462,54 +1460,6 @@
 }
 
 
-/***********************************************************************
- *           TaskFirst   (TOOLHELP.63)
- */
-BOOL16 WINAPI TaskFirst16( TASKENTRY *lpte )
-{
-    lpte->hNext = hFirstTask;
-    return TaskNext16( lpte );
-}
-
-
-/***********************************************************************
- *           TaskNext   (TOOLHELP.64)
- */
-BOOL16 WINAPI TaskNext16( TASKENTRY *lpte )
-{
-    TDB *pTask;
-    INSTANCEDATA *pInstData;
-
-    TRACE_(toolhelp)("(%p): task=%04x\n", lpte, lpte->hNext );
-    if (!lpte->hNext) return FALSE;
-
-    /* make sure that task and hInstance are valid (skip initial Wine task !) */
-    while (1) {
-        pTask = TASK_GetPtr( lpte->hNext );
-        if (!pTask || pTask->magic != TDB_MAGIC) return FALSE;
-        if (pTask->hInstance)
-            break;
-        lpte->hNext = pTask->hNext;
-    }
-    pInstData = MapSL( MAKESEGPTR( GlobalHandleToSel16(pTask->hInstance), 0 ) );
-    lpte->hTask         = lpte->hNext;
-    lpte->hTaskParent   = pTask->hParent;
-    lpte->hInst         = pTask->hInstance;
-    lpte->hModule       = pTask->hModule;
-    lpte->wSS           = SELECTOROF( pTask->teb->WOW32Reserved );
-    lpte->wSP           = OFFSETOF( pTask->teb->WOW32Reserved );
-    lpte->wStackTop     = pInstData->stacktop;
-    lpte->wStackMinimum = pInstData->stackmin;
-    lpte->wStackBottom  = pInstData->stackbottom;
-    lpte->wcEvents      = pTask->nEvents;
-    lpte->hQueue        = pTask->hQueue;
-    lstrcpynA( lpte->szModule, pTask->module_name, sizeof(lpte->szModule) );
-    lpte->wPSPOffset    = 0x100;  /*??*/
-    lpte->hNext         = pTask->hNext;
-    return TRUE;
-}
-
-
 typedef INT (WINAPI *MessageBoxA_funcptr)(HWND hWnd, LPCSTR text, LPCSTR title, UINT type);
 
 /**************************************************************************
@@ -1539,39 +1489,6 @@
 
 
 /***********************************************************************
- *           TerminateApp   (TOOLHELP.77)
- *
- * See "Undocumented Windows".
- */
-void WINAPI TerminateApp16(HTASK16 hTask, WORD wFlags)
-{
-    if (hTask && hTask != GetCurrentTask())
-    {
-        FIXME("cannot terminate task %x\n", hTask);
-        return;
-    }
-
-    if (wFlags & NO_UAE_BOX)
-    {
-        UINT16 old_mode;
-        old_mode = SetErrorMode16(0);
-        SetErrorMode16(old_mode|SEM_NOGPFAULTERRORBOX);
-    }
-    FatalAppExit16( 0, NULL );
-
-    /* hmm, we're still alive ?? */
-
-    /* check undocumented flag */
-    if (!(wFlags & 0x8000))
-        TASK_CallTaskSignalProc( USIG16_TERMINATION, hTask );
-
-    /* UndocWin says to call int 0x21/0x4c exit=0xff here,
-       but let's just call ExitThread */
-    ExitThread(0xff);
-}
-
-
-/***********************************************************************
  *           GetAppCompatFlags   (KERNEL.354)
  */
 DWORD WINAPI GetAppCompatFlags16( HTASK16 hTask )
diff --git a/dlls/kernel32/toolhelp16.c b/dlls/kernel32/toolhelp16.c
deleted file mode 100644
index 4d67b73..0000000
--- a/dlls/kernel32/toolhelp16.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Misc Toolhelp functions
- *
- * Copyright 1996 Marcus Meissner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <ctype.h>
-#include <assert.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winternl.h"
-
-#include "wine/winbase16.h"
-#include "toolhelp.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(toolhelp);
-
-/* FIXME: to make this work, we have to call back all these registered
- * functions from all over the WINE code. Someone with more knowledge than
- * me please do that. -Marcus
- */
- 
-static struct notify
-{
-    HTASK16   htask;
-    FARPROC16 lpfnCallback;
-    WORD     wFlags;
-} *notifys = NULL;
-
-static int nrofnotifys = 0;
-
-
-/***********************************************************************
- *           TaskFindHandle   (TOOLHELP.65)
- */
-BOOL16 WINAPI TaskFindHandle16( TASKENTRY *lpte, HTASK16 hTask )
-{
-    lpte->hNext = hTask;
-    return TaskNext16( lpte );
-}
-
-/***********************************************************************
- *           MemManInfo   (TOOLHELP.72)
- */
-BOOL16 WINAPI MemManInfo16( MEMMANINFO *info )
-{
-    MEMORYSTATUS status;
-
-    /*
-     * Not unsurprisingly although the documentation says you
-     * _must_ provide the size in the dwSize field, this function
-     * (under Windows) always fills the structure and returns true.
-     */
-    GlobalMemoryStatus( &status );
-    info->wPageSize            = getpagesize();
-    info->dwLargestFreeBlock   = status.dwAvailVirtual;
-    info->dwMaxPagesAvailable  = info->dwLargestFreeBlock / info->wPageSize;
-    info->dwMaxPagesLockable   = info->dwMaxPagesAvailable;
-    info->dwTotalLinearSpace   = status.dwTotalVirtual / info->wPageSize;
-    info->dwTotalUnlockedPages = info->dwTotalLinearSpace;
-    info->dwFreePages          = info->dwMaxPagesAvailable;
-    info->dwTotalPages         = info->dwTotalLinearSpace;
-    info->dwFreeLinearSpace    = info->dwMaxPagesAvailable;
-    info->dwSwapFilePages      = status.dwTotalPageFile / info->wPageSize;
-    return TRUE;
-}
-
-/***********************************************************************
- *		NotifyRegister (TOOLHELP.73)
- */
-BOOL16 WINAPI NotifyRegister16( HTASK16 htask, FARPROC16 lpfnCallback,
-                              WORD wFlags )
-{
-    int	i;
-
-    FIXME("(%x,%x,%x), semi-stub.\n",
-                      htask, (DWORD)lpfnCallback, wFlags );
-    if (!htask) htask = GetCurrentTask();
-    for (i=0;i<nrofnotifys;i++)
-        if (notifys[i].htask==htask)
-            break;
-    if (i==nrofnotifys) {
-        if (notifys==NULL)
-            notifys=HeapAlloc( GetProcessHeap(), 0,
-                                               sizeof(struct notify) );
-        else
-            notifys=HeapReAlloc( GetProcessHeap(), 0, notifys,
-                                        sizeof(struct notify)*(nrofnotifys+1));
-        if (!notifys) return FALSE;
-        nrofnotifys++;
-    }
-    notifys[i].htask=htask;
-    notifys[i].lpfnCallback=lpfnCallback;
-    notifys[i].wFlags=wFlags;
-    return TRUE;
-}
-
-/***********************************************************************
- *		NotifyUnregister (TOOLHELP.74)
- */
-BOOL16 WINAPI NotifyUnregister16( HTASK16 htask )
-{
-    int	i;
-
-    FIXME("(%x), semi-stub.\n", htask );
-    if (!htask) htask = GetCurrentTask();
-    for (i=nrofnotifys;i--;)
-        if (notifys[i].htask==htask)
-            break;
-    if (i==-1)
-        return FALSE;
-    memcpy(notifys+i,notifys+(i+1),sizeof(struct notify)*(nrofnotifys-i-1));
-    notifys=HeapReAlloc( GetProcessHeap(), 0, notifys,
-                                        (nrofnotifys-1)*sizeof(struct notify));
-    nrofnotifys--;
-    return TRUE;
-}
-
-/***********************************************************************
- *		StackTraceCSIPFirst (TOOLHELP.67)
- */
-BOOL16 WINAPI StackTraceCSIPFirst16(STACKTRACEENTRY *ste, WORD wSS, WORD wCS, WORD wIP, WORD wBP)
-{
-    FIXME("(%p, ss %04x, cs %04x, ip %04x, bp %04x): stub.\n", ste, wSS, wCS, wIP, wBP);
-    return TRUE;
-}
-
-/***********************************************************************
- *		StackTraceFirst (TOOLHELP.66)
- */
-BOOL16 WINAPI StackTraceFirst16(STACKTRACEENTRY *ste, HTASK16 Task)
-{
-    FIXME("(%p, %04x), stub.\n", ste, Task);
-    return TRUE;
-}
-
-/***********************************************************************
- *		StackTraceNext (TOOLHELP.68)
- */
-BOOL16 WINAPI StackTraceNext16(STACKTRACEENTRY *ste)
-{
-    FIXME("(%p), stub.\n", ste);
-    return TRUE;
-}
-
-/***********************************************************************
- *		InterruptRegister (TOOLHELP.75)
- */
-BOOL16 WINAPI InterruptRegister16( HTASK16 task, FARPROC callback )
-{
-    FIXME("(%04x, %p), stub.\n", task, callback);
-    return TRUE;
-}
-
-/***********************************************************************
- *		InterruptUnRegister (TOOLHELP.76)
- */
-BOOL16 WINAPI InterruptUnRegister16( HTASK16 task )
-{
-    FIXME("(%04x), stub.\n", task);
-    return TRUE;
-}
-
-/***********************************************************************
- *           TimerCount   (TOOLHELP.80)
- */
-BOOL16 WINAPI TimerCount16( TIMERINFO *pTimerInfo )
-{
-    /* FIXME
-     * In standard mode, dwmsSinceStart = dwmsThisVM
-     *
-     * I tested this, under Windows in enhanced mode, and
-     * if you never switch VM (ie start/stop DOS) these
-     * values should be the same as well.
-     *
-     * Also, Wine should adjust for the hardware timer
-     * to reduce the amount of error to ~1ms.
-     * I can't be bothered, can you?
-     */
-    pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount();
-    return TRUE;
-}
-
-/***********************************************************************
- *           SystemHeapInfo   (TOOLHELP.71)
- */
-BOOL16 WINAPI SystemHeapInfo16( SYSHEAPINFO *pHeapInfo )
-{
-    STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
-    HANDLE16 oldDS = stack16->ds;
-    WORD user = LoadLibrary16( "USER.EXE" );
-    WORD gdi = LoadLibrary16( "GDI.EXE" );
-    stack16->ds = user;
-    pHeapInfo->wUserFreePercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
-    stack16->ds = gdi;
-    pHeapInfo->wGDIFreePercent  = (int)LocalCountFree16() * 100 / LocalHeapSize16();
-    stack16->ds = oldDS;
-    pHeapInfo->hUserSegment = user;
-    pHeapInfo->hGDISegment  = gdi;
-    FreeLibrary16( user );
-    FreeLibrary16( gdi );
-    return TRUE;
-}
diff --git a/dlls/toolhelp.dll16/Makefile.in b/dlls/toolhelp.dll16/Makefile.in
new file mode 100644
index 0000000..74b45f2
--- /dev/null
+++ b/dlls/toolhelp.dll16/Makefile.in
@@ -0,0 +1,13 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = toolhelp.dll16
+IMPORTS   = kernel32
+EXTRADLLFLAGS = -Wb,--subsystem,win16
+
+C_SRCS = toolhelp.c
+
+@MAKE_DLL_RULES@
+
+@DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/dlls/toolhelp.dll16/toolhelp.c b/dlls/toolhelp.dll16/toolhelp.c
new file mode 100644
index 0000000..fb001ea
--- /dev/null
+++ b/dlls/toolhelp.dll16/toolhelp.c
@@ -0,0 +1,737 @@
+/*
+ * Toolhelp functions
+ *
+ * Copyright 1996 Marcus Meissner
+ * Copyright 2009 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <ctype.h>
+#include <assert.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "wownt32.h"
+
+#include "wine/winbase16.h"
+#include "toolhelp.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(toolhelp);
+
+#include "pshpack1.h"
+
+typedef struct
+{
+    void     *base;          /* Base address (0 if discarded) */
+    DWORD     size;          /* Size in bytes (0 indicates a free block) */
+    HGLOBAL16 handle;        /* Handle for this block */
+    HGLOBAL16 hOwner;        /* Owner of this block */
+    BYTE      lockCount;     /* Count of GlobalFix() calls */
+    BYTE      pageLockCount; /* Count of GlobalPageLock() calls */
+    BYTE      flags;         /* Allocation flags */
+    BYTE      selCount;      /* Number of selectors allocated for this block */
+} GLOBALARENA;
+
+#define GLOBAL_MAX_COUNT  8192        /* Max number of allocated blocks */
+
+typedef struct
+{
+    WORD check;                 /* 00 Heap checking flag */
+    WORD freeze;                /* 02 Heap frozen flag */
+    WORD items;                 /* 04 Count of items on the heap */
+    WORD first;                 /* 06 First item of the heap */
+    WORD pad1;                  /* 08 Always 0 */
+    WORD last;                  /* 0a Last item of the heap */
+    WORD pad2;                  /* 0c Always 0 */
+    BYTE ncompact;              /* 0e Compactions counter */
+    BYTE dislevel;              /* 0f Discard level */
+    DWORD distotal;             /* 10 Total bytes discarded */
+    WORD htable;                /* 14 Pointer to handle table */
+    WORD hfree;                 /* 16 Pointer to free handle table */
+    WORD hdelta;                /* 18 Delta to expand the handle table */
+    WORD expand;                /* 1a Pointer to expand function (unused) */
+    WORD pstat;                 /* 1c Pointer to status structure (unused) */
+    FARPROC16 notify;           /* 1e Pointer to LocalNotify() function */
+    WORD lock;                  /* 22 Lock count for the heap */
+    WORD extra;                 /* 24 Extra bytes to allocate when expanding */
+    WORD minsize;               /* 26 Minimum size of the heap */
+    WORD magic;                 /* 28 Magic number */
+} LOCALHEAPINFO;
+
+typedef struct
+{
+/* Arena header */
+    WORD prev;          /* Previous arena | arena type */
+    WORD next;          /* Next arena */
+/* Start of the memory block or free-list info */
+    WORD size;          /* Size of the free block */
+    WORD free_prev;     /* Previous free block */
+    WORD free_next;     /* Next free block */
+} LOCALARENA;
+
+#define LOCAL_ARENA_HEADER_SIZE      4
+#define LOCAL_ARENA_HEADER( handle) ((handle) - LOCAL_ARENA_HEADER_SIZE)
+#define LOCAL_ARENA_PTR(ptr,arena)  ((LOCALARENA *)((char *)(ptr)+(arena)))
+
+typedef struct
+{
+    WORD null;        /* Always 0 */
+    DWORD old_ss_sp;  /* Stack pointer; used by SwitchTaskTo() */
+    WORD heap;        /* Pointer to the local heap information (if any) */
+    WORD atomtable;   /* Pointer to the local atom table (if any) */
+    WORD stacktop;    /* Top of the stack */
+    WORD stackmin;    /* Lowest stack address used so far */
+    WORD stackbottom; /* Bottom of the stack */
+} INSTANCEDATA;
+
+typedef struct _THHOOK
+{
+    HANDLE16   hGlobalHeap;         /* 00 (handle BURGERMASTER) */
+    WORD       pGlobalHeap;         /* 02 (selector BURGERMASTER) */
+    HMODULE16  hExeHead;            /* 04 hFirstModule */
+    HMODULE16  hExeSweep;           /* 06 (unused) */
+    HANDLE16   TopPDB;              /* 08 (handle of KERNEL PDB) */
+    HANDLE16   HeadPDB;             /* 0A (first PDB in list) */
+    HANDLE16   TopSizePDB;          /* 0C (unused) */
+    HTASK16    HeadTDB;             /* 0E hFirstTask */
+    HTASK16    CurTDB;              /* 10 hCurrentTask */
+    HTASK16    LoadTDB;             /* 12 (unused) */
+    HTASK16    LockTDB;             /* 14 hLockedTask */
+} THHOOK;
+
+typedef struct _NE_MODULE
+{
+    WORD      ne_magic;         /* 00 'NE' signature */
+    WORD      count;            /* 02 Usage count (ne_ver/ne_rev on disk) */
+    WORD      ne_enttab;        /* 04 Near ptr to entry table */
+    HMODULE16 next;             /* 06 Selector to next module (ne_cbenttab on disk) */
+    WORD      dgroup_entry;     /* 08 Near ptr to segment entry for DGROUP (ne_crc on disk) */
+    WORD      fileinfo;         /* 0a Near ptr to file info (OFSTRUCT) (ne_crc on disk) */
+    WORD      ne_flags;         /* 0c Module flags */
+    WORD      ne_autodata;      /* 0e Logical segment for DGROUP */
+    WORD      ne_heap;          /* 10 Initial heap size */
+    WORD      ne_stack;         /* 12 Initial stack size */
+    DWORD     ne_csip;          /* 14 Initial cs:ip */
+    DWORD     ne_sssp;          /* 18 Initial ss:sp */
+    WORD      ne_cseg;          /* 1c Number of segments in segment table */
+    WORD      ne_cmod;          /* 1e Number of module references */
+    WORD      ne_cbnrestab;     /* 20 Size of non-resident names table */
+    WORD      ne_segtab;        /* 22 Near ptr to segment table */
+    WORD      ne_rsrctab;       /* 24 Near ptr to resource table */
+    WORD      ne_restab;        /* 26 Near ptr to resident names table */
+    WORD      ne_modtab;        /* 28 Near ptr to module reference table */
+    WORD      ne_imptab;        /* 2a Near ptr to imported names table */
+    DWORD     ne_nrestab;       /* 2c File offset of non-resident names table */
+    WORD      ne_cmovent;       /* 30 Number of moveable entries in entry table*/
+    WORD      ne_align;         /* 32 Alignment shift count */
+    WORD      ne_cres;          /* 34 # of resource segments */
+    BYTE      ne_exetyp;        /* 36 Operating system flags */
+    BYTE      ne_flagsothers;   /* 37 Misc. flags */
+    HANDLE16  dlls_to_init;     /* 38 List of DLLs to initialize (ne_pretthunks on disk) */
+    HANDLE16  nrname_handle;    /* 3a Handle to non-resident name table (ne_psegrefbytes on disk) */
+    WORD      ne_swaparea;      /* 3c Min. swap area size */
+    WORD      ne_expver;        /* 3e Expected Windows version */
+    /* From here, these are extra fields not present in normal Windows */
+    HMODULE   module32;         /* PE module handle for Win32 modules */
+    HMODULE   owner32;          /* PE module containing this one for 16-bit builtins */
+    HMODULE16 self;             /* Handle for this module */
+    WORD      self_loading_sel; /* Selector used for self-loading apps. */
+    LPVOID    rsrc32_map;       /* HRSRC 16->32 map (for 32-bit modules) */
+    LPCVOID   mapping;          /* mapping of the binary file */
+    SIZE_T    mapping_size;     /* size of the file mapping */
+} NE_MODULE;
+
+#include "poppack.h"
+
+#define TDB_MAGIC    ('T' | ('D' << 8))
+
+/* FIXME: to make this work, we have to call back all these registered
+ * functions from all over the WINE code. Someone with more knowledge than
+ * me please do that. -Marcus
+ */
+
+static struct notify
+{
+    HTASK16   htask;
+    FARPROC16 lpfnCallback;
+    WORD     wFlags;
+} *notifys = NULL;
+
+static int nrofnotifys = 0;
+
+static THHOOK *get_thhook(void)
+{
+    static THHOOK *thhook;
+
+    if (!thhook) thhook = MapSL( (SEGPTR)GetProcAddress16( GetModuleHandle16("KERNEL"), (LPCSTR)332 ));
+    return thhook;
+}
+
+static GLOBALARENA *get_global_arena(void)
+{
+    return *(GLOBALARENA **)get_thhook();
+}
+
+static LOCALHEAPINFO *get_local_heap( HANDLE16 ds )
+{
+    INSTANCEDATA *ptr = MapSL( MAKESEGPTR( ds, 0 ));
+
+    if (!ptr || !ptr->heap) return NULL;
+    return (LOCALHEAPINFO*)((char*)ptr + ptr->heap);
+}
+
+
+/***********************************************************************
+ *           GlobalHandleToSel   (TOOLHELP.50)
+ */
+WORD WINAPI GlobalHandleToSel16( HGLOBAL16 handle )
+{
+    if (!handle) return 0;
+    if (!(handle & 7)) return handle - 1;
+    return handle | 7;
+}
+
+
+/***********************************************************************
+ *           GlobalFirst   (TOOLHELP.51)
+ */
+BOOL16 WINAPI GlobalFirst16( GLOBALENTRY *pGlobal, WORD wFlags )
+{
+    if (wFlags == GLOBAL_LRU) return FALSE;
+    pGlobal->dwNext = 0;
+    return GlobalNext16( pGlobal, wFlags );
+}
+
+
+/***********************************************************************
+ *           GlobalNext   (TOOLHELP.52)
+ */
+BOOL16 WINAPI GlobalNext16( GLOBALENTRY *pGlobal, WORD wFlags)
+{
+    GLOBALARENA *pGlobalArena = get_global_arena();
+    GLOBALARENA *pArena;
+
+    if (pGlobal->dwNext >= GLOBAL_MAX_COUNT) return FALSE;
+    pArena = pGlobalArena + pGlobal->dwNext;
+    if (wFlags == GLOBAL_FREE)  /* only free blocks */
+    {
+        int i;
+        for (i = pGlobal->dwNext; i < GLOBAL_MAX_COUNT; i++, pArena++)
+            if (pArena->size == 0) break;  /* block is free */
+        if (i >= GLOBAL_MAX_COUNT) return FALSE;
+        pGlobal->dwNext = i;
+    }
+
+    pGlobal->dwAddress    = (DWORD_PTR)pArena->base;
+    pGlobal->dwBlockSize  = pArena->size;
+    pGlobal->hBlock       = pArena->handle;
+    pGlobal->wcLock       = pArena->lockCount;
+    pGlobal->wcPageLock   = pArena->pageLockCount;
+    pGlobal->wFlags       = (GetCurrentPDB16() == pArena->hOwner);
+    pGlobal->wHeapPresent = FALSE;
+    pGlobal->hOwner       = pArena->hOwner;
+    pGlobal->wType        = GT_UNKNOWN;
+    pGlobal->wData        = 0;
+    pGlobal->dwNext++;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GlobalInfo   (TOOLHELP.53)
+ */
+BOOL16 WINAPI GlobalInfo16( GLOBALINFO *pInfo )
+{
+    GLOBALARENA *pGlobalArena = get_global_arena();
+    GLOBALARENA *pArena;
+    int i;
+
+    pInfo->wcItems = GLOBAL_MAX_COUNT;
+    pInfo->wcItemsFree = 0;
+    pInfo->wcItemsLRU = 0;
+    for (i = 0, pArena = pGlobalArena; i < GLOBAL_MAX_COUNT; i++, pArena++)
+        if (pArena->size == 0) pInfo->wcItemsFree++;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GlobalEntryHandle   (TOOLHELP.54)
+ */
+BOOL16 WINAPI GlobalEntryHandle16( GLOBALENTRY *pGlobal, HGLOBAL16 hItem )
+{
+    GLOBALARENA *pGlobalArena = get_global_arena();
+    GLOBALARENA *pArena = pGlobalArena + (hItem >> __AHSHIFT);
+
+    pGlobal->dwAddress    = (DWORD_PTR)pArena->base;
+    pGlobal->dwBlockSize  = pArena->size;
+    pGlobal->hBlock       = pArena->handle;
+    pGlobal->wcLock       = pArena->lockCount;
+    pGlobal->wcPageLock   = pArena->pageLockCount;
+    pGlobal->wFlags       = (GetCurrentPDB16() == pArena->hOwner);
+    pGlobal->wHeapPresent = FALSE;
+    pGlobal->hOwner       = pArena->hOwner;
+    pGlobal->wType        = GT_UNKNOWN;
+    pGlobal->wData        = 0;
+    pGlobal->dwNext++;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GlobalEntryModule   (TOOLHELP.55)
+ */
+BOOL16 WINAPI GlobalEntryModule16( GLOBALENTRY *pGlobal, HMODULE16 hModule,
+                                 WORD wSeg )
+{
+    FIXME("(%p, 0x%04x, 0x%04x), stub.\n", pGlobal, hModule, wSeg);
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           LocalInfo   (TOOLHELP.56)
+ */
+BOOL16 WINAPI LocalInfo16( LOCALINFO *pLocalInfo, HGLOBAL16 handle )
+{
+    LOCALHEAPINFO *pInfo = get_local_heap( SELECTOROF(WOWGlobalLock16(handle)) );
+    if (!pInfo) return FALSE;
+    pLocalInfo->wcItems = pInfo->items;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LocalFirst   (TOOLHELP.57)
+ */
+BOOL16 WINAPI LocalFirst16( LOCALENTRY *pLocalEntry, HGLOBAL16 handle )
+{
+    WORD ds = GlobalHandleToSel16( handle );
+    char *ptr = MapSL( MAKESEGPTR( ds, 0 ) );
+    LOCALHEAPINFO *pInfo = get_local_heap( ds );
+    if (!pInfo) return FALSE;
+
+    pLocalEntry->hHandle   = pInfo->first + LOCAL_ARENA_HEADER_SIZE;
+    pLocalEntry->wAddress  = pLocalEntry->hHandle;
+    pLocalEntry->wFlags    = LF_FIXED;
+    pLocalEntry->wcLock    = 0;
+    pLocalEntry->wType     = LT_NORMAL;
+    pLocalEntry->hHeap     = handle;
+    pLocalEntry->wHeapType = NORMAL_HEAP;
+    pLocalEntry->wNext     = LOCAL_ARENA_PTR(ptr,pInfo->first)->next;
+    pLocalEntry->wSize     = pLocalEntry->wNext - pLocalEntry->hHandle;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LocalNext   (TOOLHELP.58)
+ */
+BOOL16 WINAPI LocalNext16( LOCALENTRY *pLocalEntry )
+{
+    WORD ds = GlobalHandleToSel16( pLocalEntry->hHeap );
+    char *ptr = MapSL( MAKESEGPTR( ds, 0 ) );
+    LOCALARENA *pArena;
+
+    if (!get_local_heap( ds )) return FALSE;
+    if (!pLocalEntry->wNext) return FALSE;
+    pArena = LOCAL_ARENA_PTR( ptr, pLocalEntry->wNext );
+
+    pLocalEntry->hHandle   = pLocalEntry->wNext + LOCAL_ARENA_HEADER_SIZE;
+    pLocalEntry->wAddress  = pLocalEntry->hHandle;
+    pLocalEntry->wFlags    = (pArena->prev & 3) + 1;
+    pLocalEntry->wcLock    = 0;
+    pLocalEntry->wType     = LT_NORMAL;
+    if (pArena->next != pLocalEntry->wNext)  /* last one? */
+        pLocalEntry->wNext = pArena->next;
+    else
+        pLocalEntry->wNext = 0;
+    pLocalEntry->wSize     = pLocalEntry->wNext - pLocalEntry->hHandle;
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *	    ModuleFirst    (TOOLHELP.59)
+ */
+BOOL16 WINAPI ModuleFirst16( MODULEENTRY *lpme )
+{
+    lpme->wNext = get_thhook()->hExeHead;
+    return ModuleNext16( lpme );
+}
+
+
+/**********************************************************************
+ *	    ModuleNext    (TOOLHELP.60)
+ */
+BOOL16 WINAPI ModuleNext16( MODULEENTRY *lpme )
+{
+    NE_MODULE *pModule;
+    char *name;
+
+    if (!lpme->wNext) return FALSE;
+    if (!(pModule = GlobalLock16( GetExePtr(lpme->wNext) ))) return FALSE;
+    name = (char *)pModule + pModule->ne_restab;
+    memcpy( lpme->szModule, name + 1, min(*name, MAX_MODULE_NAME) );
+    lpme->szModule[min(*name, MAX_MODULE_NAME)] = '\0';
+    lpme->hModule = lpme->wNext;
+    lpme->wcUsage = pModule->count;
+    name = ((OFSTRUCT *)((char*)pModule + pModule->fileinfo))->szPathName;
+    lstrcpynA( lpme->szExePath, name, sizeof(lpme->szExePath) );
+    lpme->wNext = pModule->next;
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *	    ModuleFindName    (TOOLHELP.61)
+ */
+BOOL16 WINAPI ModuleFindName16( MODULEENTRY *lpme, LPCSTR name )
+{
+    lpme->wNext = GetModuleHandle16( name );
+    return ModuleNext16( lpme );
+}
+
+
+/**********************************************************************
+ *	    ModuleFindHandle    (TOOLHELP.62)
+ */
+BOOL16 WINAPI ModuleFindHandle16( MODULEENTRY *lpme, HMODULE16 hModule )
+{
+    hModule = GetExePtr( hModule );
+    lpme->wNext = hModule;
+    return ModuleNext16( lpme );
+}
+
+
+/***********************************************************************
+ *           TaskFirst   (TOOLHELP.63)
+ */
+BOOL16 WINAPI TaskFirst16( TASKENTRY *lpte )
+{
+    lpte->hNext = get_thhook()->HeadTDB;
+    return TaskNext16( lpte );
+}
+
+
+/***********************************************************************
+ *           TaskNext   (TOOLHELP.64)
+ */
+BOOL16 WINAPI TaskNext16( TASKENTRY *lpte )
+{
+    TDB *pTask;
+    INSTANCEDATA *pInstData;
+
+    TRACE_(toolhelp)("(%p): task=%04x\n", lpte, lpte->hNext );
+    if (!lpte->hNext) return FALSE;
+
+    /* make sure that task and hInstance are valid (skip initial Wine task !) */
+    while (1) {
+        pTask = GlobalLock16( lpte->hNext );
+        if (!pTask || pTask->magic != TDB_MAGIC) return FALSE;
+        if (pTask->hInstance)
+            break;
+        lpte->hNext = pTask->hNext;
+    }
+    pInstData = MapSL( MAKESEGPTR( GlobalHandleToSel16(pTask->hInstance), 0 ) );
+    lpte->hTask         = lpte->hNext;
+    lpte->hTaskParent   = pTask->hParent;
+    lpte->hInst         = pTask->hInstance;
+    lpte->hModule       = pTask->hModule;
+    lpte->wSS           = SELECTOROF( pTask->teb->WOW32Reserved );
+    lpte->wSP           = OFFSETOF( pTask->teb->WOW32Reserved );
+    lpte->wStackTop     = pInstData->stacktop;
+    lpte->wStackMinimum = pInstData->stackmin;
+    lpte->wStackBottom  = pInstData->stackbottom;
+    lpte->wcEvents      = pTask->nEvents;
+    lpte->hQueue        = pTask->hQueue;
+    lstrcpynA( lpte->szModule, pTask->module_name, sizeof(lpte->szModule) );
+    lpte->wPSPOffset    = 0x100;  /*??*/
+    lpte->hNext         = pTask->hNext;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           TaskFindHandle   (TOOLHELP.65)
+ */
+BOOL16 WINAPI TaskFindHandle16( TASKENTRY *lpte, HTASK16 hTask )
+{
+    lpte->hNext = hTask;
+    return TaskNext16( lpte );
+}
+
+
+/***********************************************************************
+ *           MemManInfo   (TOOLHELP.72)
+ */
+BOOL16 WINAPI MemManInfo16( MEMMANINFO *info )
+{
+    MEMORYSTATUS status;
+
+    /*
+     * Not unsurprisingly although the documentation says you
+     * _must_ provide the size in the dwSize field, this function
+     * (under Windows) always fills the structure and returns true.
+     */
+    GlobalMemoryStatus( &status );
+    info->wPageSize            = getpagesize();
+    info->dwLargestFreeBlock   = status.dwAvailVirtual;
+    info->dwMaxPagesAvailable  = info->dwLargestFreeBlock / info->wPageSize;
+    info->dwMaxPagesLockable   = info->dwMaxPagesAvailable;
+    info->dwTotalLinearSpace   = status.dwTotalVirtual / info->wPageSize;
+    info->dwTotalUnlockedPages = info->dwTotalLinearSpace;
+    info->dwFreePages          = info->dwMaxPagesAvailable;
+    info->dwTotalPages         = info->dwTotalLinearSpace;
+    info->dwFreeLinearSpace    = info->dwMaxPagesAvailable;
+    info->dwSwapFilePages      = status.dwTotalPageFile / info->wPageSize;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *		NotifyRegister (TOOLHELP.73)
+ */
+BOOL16 WINAPI NotifyRegister16( HTASK16 htask, FARPROC16 lpfnCallback,
+                              WORD wFlags )
+{
+    int	i;
+
+    FIXME("(%x,%x,%x), semi-stub.\n",
+                      htask, (DWORD)lpfnCallback, wFlags );
+    if (!htask) htask = GetCurrentTask();
+    for (i=0;i<nrofnotifys;i++)
+        if (notifys[i].htask==htask)
+            break;
+    if (i==nrofnotifys) {
+        if (notifys==NULL)
+            notifys=HeapAlloc( GetProcessHeap(), 0,
+                                               sizeof(struct notify) );
+        else
+            notifys=HeapReAlloc( GetProcessHeap(), 0, notifys,
+                                        sizeof(struct notify)*(nrofnotifys+1));
+        if (!notifys) return FALSE;
+        nrofnotifys++;
+    }
+    notifys[i].htask=htask;
+    notifys[i].lpfnCallback=lpfnCallback;
+    notifys[i].wFlags=wFlags;
+    return TRUE;
+}
+
+/***********************************************************************
+ *		NotifyUnregister (TOOLHELP.74)
+ */
+BOOL16 WINAPI NotifyUnregister16( HTASK16 htask )
+{
+    int	i;
+
+    FIXME("(%x), semi-stub.\n", htask );
+    if (!htask) htask = GetCurrentTask();
+    for (i=nrofnotifys;i--;)
+        if (notifys[i].htask==htask)
+            break;
+    if (i==-1)
+        return FALSE;
+    memcpy(notifys+i,notifys+(i+1),sizeof(struct notify)*(nrofnotifys-i-1));
+    notifys=HeapReAlloc( GetProcessHeap(), 0, notifys,
+                                        (nrofnotifys-1)*sizeof(struct notify));
+    nrofnotifys--;
+    return TRUE;
+}
+
+/***********************************************************************
+ *		StackTraceCSIPFirst (TOOLHELP.67)
+ */
+BOOL16 WINAPI StackTraceCSIPFirst16(STACKTRACEENTRY *ste, WORD wSS, WORD wCS, WORD wIP, WORD wBP)
+{
+    FIXME("(%p, ss %04x, cs %04x, ip %04x, bp %04x): stub.\n", ste, wSS, wCS, wIP, wBP);
+    return TRUE;
+}
+
+/***********************************************************************
+ *		StackTraceFirst (TOOLHELP.66)
+ */
+BOOL16 WINAPI StackTraceFirst16(STACKTRACEENTRY *ste, HTASK16 Task)
+{
+    FIXME("(%p, %04x), stub.\n", ste, Task);
+    return TRUE;
+}
+
+/***********************************************************************
+ *		StackTraceNext (TOOLHELP.68)
+ */
+BOOL16 WINAPI StackTraceNext16(STACKTRACEENTRY *ste)
+{
+    FIXME("(%p), stub.\n", ste);
+    return TRUE;
+}
+
+/***********************************************************************
+ *		InterruptRegister (TOOLHELP.75)
+ */
+BOOL16 WINAPI InterruptRegister16( HTASK16 task, FARPROC callback )
+{
+    FIXME("(%04x, %p), stub.\n", task, callback);
+    return TRUE;
+}
+
+/***********************************************************************
+ *		InterruptUnRegister (TOOLHELP.76)
+ */
+BOOL16 WINAPI InterruptUnRegister16( HTASK16 task )
+{
+    FIXME("(%04x), stub.\n", task);
+    return TRUE;
+}
+
+/***********************************************************************
+ *           TerminateApp   (TOOLHELP.77)
+ *
+ * See "Undocumented Windows".
+ */
+void WINAPI TerminateApp16(HTASK16 hTask, WORD wFlags)
+{
+    if (hTask && hTask != GetCurrentTask())
+    {
+        FIXME("cannot terminate task %x\n", hTask);
+        return;
+    }
+
+#if 0  /* FIXME */
+    /* check undocumented flag */
+    if (!(wFlags & 0x8000))
+        TASK_CallTaskSignalProc( USIG16_TERMINATION, hTask );
+#endif
+
+    /* UndocWin says to call int 0x21/0x4c exit=0xff here,
+       but let's just call ExitThread */
+    ExitThread(0xff);
+}
+
+/***********************************************************************
+ *           MemoryRead   (TOOLHELP.78)
+ */
+DWORD WINAPI MemoryRead16( WORD sel, DWORD offset, void *buffer, DWORD count )
+{
+    LDT_ENTRY entry;
+    DWORD limit;
+
+    wine_ldt_get_entry( sel, &entry );
+    if (wine_ldt_is_empty( &entry )) return 0;
+    limit = wine_ldt_get_limit( &entry );
+    if (offset > limit) return 0;
+    if (offset + count > limit + 1) count = limit + 1 - offset;
+    memcpy( buffer, (char *)wine_ldt_get_base(&entry) + offset, count );
+    return count;
+}
+
+
+/***********************************************************************
+ *           MemoryWrite   (TOOLHELP.79)
+ */
+DWORD WINAPI MemoryWrite16( WORD sel, DWORD offset, void *buffer, DWORD count )
+{
+    LDT_ENTRY entry;
+    DWORD limit;
+
+    wine_ldt_get_entry( sel, &entry );
+    if (wine_ldt_is_empty( &entry )) return 0;
+    limit = wine_ldt_get_limit( &entry );
+    if (offset > limit) return 0;
+    if (offset + count > limit) count = limit + 1 - offset;
+    memcpy( (char *)wine_ldt_get_base(&entry) + offset, buffer, count );
+    return count;
+}
+
+/***********************************************************************
+ *           TimerCount   (TOOLHELP.80)
+ */
+BOOL16 WINAPI TimerCount16( TIMERINFO *pTimerInfo )
+{
+    /* FIXME
+     * In standard mode, dwmsSinceStart = dwmsThisVM
+     *
+     * I tested this, under Windows in enhanced mode, and
+     * if you never switch VM (ie start/stop DOS) these
+     * values should be the same as well.
+     *
+     * Also, Wine should adjust for the hardware timer
+     * to reduce the amount of error to ~1ms.
+     * I can't be bothered, can you?
+     */
+    pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount();
+    return TRUE;
+}
+
+/***********************************************************************
+ *           SystemHeapInfo   (TOOLHELP.71)
+ */
+BOOL16 WINAPI SystemHeapInfo16( SYSHEAPINFO *pHeapInfo )
+{
+    STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
+    HANDLE16 oldDS = stack16->ds;
+    WORD user = LoadLibrary16( "USER.EXE" );
+    WORD gdi = LoadLibrary16( "GDI.EXE" );
+    stack16->ds = user;
+    pHeapInfo->wUserFreePercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
+    stack16->ds = gdi;
+    pHeapInfo->wGDIFreePercent  = (int)LocalCountFree16() * 100 / LocalHeapSize16();
+    stack16->ds = oldDS;
+    pHeapInfo->hUserSegment = user;
+    pHeapInfo->hGDISegment  = gdi;
+    FreeLibrary16( user );
+    FreeLibrary16( gdi );
+    return TRUE;
+}
+
+/***********************************************************************
+ *           Local32Info   (TOOLHELP.84)
+ */
+BOOL16 WINAPI Local32Info16( LOCAL32INFO *pLocal32Info, HGLOBAL16 handle )
+{
+    FIXME( "Call Local32Info16 in kernel\n" );
+    return FALSE;
+}
+
+/***********************************************************************
+ *           Local32First   (TOOLHELP.85)
+ */
+BOOL16 WINAPI Local32First16( LOCAL32ENTRY *pLocal32Entry, HGLOBAL16 handle )
+{
+    FIXME( "Call Local32First16 in kernel\n" );
+    return FALSE;
+}
+
+/***********************************************************************
+ *           Local32Next   (TOOLHELP.86)
+ */
+BOOL16 WINAPI Local32Next16( LOCAL32ENTRY *pLocal32Entry )
+{
+    FIXME( "Call Local32Next16 in kernel\n" );
+    return FALSE;
+}
diff --git a/dlls/kernel32/toolhelp.spec b/dlls/toolhelp.dll16/toolhelp.dll16.spec
similarity index 100%
rename from dlls/kernel32/toolhelp.spec
rename to dlls/toolhelp.dll16/toolhelp.dll16.spec
diff --git a/dlls/kernel32/toolhelp.h b/dlls/toolhelp.dll16/toolhelp.h
similarity index 100%
rename from dlls/kernel32/toolhelp.h
rename to dlls/toolhelp.dll16/toolhelp.h