Moved toolhelp implementation into kernel32 dll.

diff --git a/dlls/kernel/toolhelp.c b/dlls/kernel/toolhelp.c
new file mode 100644
index 0000000..c75e899
--- /dev/null
+++ b/dlls/kernel/toolhelp.c
@@ -0,0 +1,370 @@
+/*
+ * Misc Toolhelp functions
+ *
+ * Copyright 1996 Marcus Meissner
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <assert.h>
+#include "winbase.h"
+#include "wine/winbase16.h"
+#include "winerror.h"
+#include "local.h"
+#include "process.h"
+#include "tlhelp32.h"
+#include "toolhelp.h"
+#include "heap.h"
+#include "server.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(toolhelp);
+
+
+/* FIXME: to make this working, we have to callback 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 FARPROC16 HookNotify = NULL;
+
+/***********************************************************************
+ *		NotifyRegister16
+ */
+BOOL16 WINAPI NotifyRegister16( HTASK16 htask, FARPROC16 lpfnCallback,
+                              WORD wFlags )
+{
+    int	i;
+
+    TRACE("(%x,%lx,%x) called.\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=(struct notify*)HeapAlloc( GetProcessHeap(), 0,
+                                               sizeof(struct notify) );
+        else
+            notifys=(struct notify*)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;
+}
+
+/***********************************************************************
+ *		NotifyUnregister16
+ */
+BOOL16 WINAPI NotifyUnregister16( HTASK16 htask )
+{
+    int	i;
+    
+    TRACE("(%x) called.\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=(struct notify*)HeapReAlloc( GetProcessHeap(), 0, notifys,
+                                        (nrofnotifys-1)*sizeof(struct notify));
+    nrofnotifys--;
+    return TRUE;
+}
+
+/***********************************************************************
+ *		StackTraceCSIPFirst16
+ */
+BOOL16 WINAPI StackTraceCSIPFirst16(STACKTRACEENTRY *ste, WORD wSS, WORD wCS, WORD wIP, WORD wBP)
+{
+    return TRUE;
+}
+
+/***********************************************************************
+ *		StackTraceFirst16
+ */
+BOOL16 WINAPI StackTraceFirst16(STACKTRACEENTRY *ste, HTASK16 Task)
+{
+    return TRUE;
+}
+
+/***********************************************************************
+ *		StackTraceNext16
+ */
+BOOL16 WINAPI StackTraceNext16(STACKTRACEENTRY *ste)
+{
+    return TRUE;
+}
+
+/***********************************************************************
+ *		InterruptRegister16
+ */
+BOOL16 WINAPI InterruptRegister16( HTASK16 task, FARPROC callback )
+{
+    return TRUE;
+}
+
+/***********************************************************************
+ *		InterruptUnRegister16
+ */
+BOOL16 WINAPI InterruptUnRegister16( HTASK16 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 )
+{
+    WORD user = LoadLibrary16( "USER.EXE" );
+    WORD gdi = LoadLibrary16( "GDI.EXE" );
+    pHeapInfo->wUserFreePercent = (int)LOCAL_CountFree(user) * 100 / LOCAL_HeapSize(user);
+    pHeapInfo->wGDIFreePercent  = (int)LOCAL_CountFree(gdi) * 100 / LOCAL_HeapSize(gdi);
+    pHeapInfo->hUserSegment = user;
+    pHeapInfo->hGDISegment  = gdi;
+    FreeLibrary16( user );
+    FreeLibrary16( gdi );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ToolHelpHook                             (KERNEL.341)
+ *	see "Undocumented Windows"
+ */
+FARPROC16 WINAPI ToolHelpHook16(FARPROC16 lpfnNotifyHandler)
+{
+FARPROC16 tmp;
+	tmp = HookNotify;
+	HookNotify = lpfnNotifyHandler;
+	/* just return previously installed notification function */
+	return tmp;
+}
+
+
+/***********************************************************************
+ *           CreateToolhelp32Snapshot			(KERNEL32.179)
+ */
+HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) 
+{
+    struct create_snapshot_request *req = get_req_buffer();
+
+    TRACE("%lx,%lx\n", flags, process );
+    if (!(flags & (TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE)))
+    {
+        FIXME("flags %lx not implemented\n", flags );
+        SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+        return INVALID_HANDLE_VALUE;
+    }
+    
+    /* Now do the snapshot */
+    req->flags   = flags & ~TH32CS_INHERIT;
+    req->inherit = (flags & TH32CS_INHERIT) != 0;
+    req->pid     = (void *)process;
+    server_call( REQ_CREATE_SNAPSHOT );
+    return req->handle;
+}
+
+
+/***********************************************************************
+ *		TOOLHELP_Thread32Next
+ *
+ * Implementation of Thread32First/Next
+ */
+static BOOL TOOLHELP_Thread32Next( HANDLE handle, LPTHREADENTRY32 lpte, BOOL first )
+{
+    struct next_thread_request *req = get_req_buffer();
+
+    if (lpte->dwSize < sizeof(THREADENTRY32))
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        ERR("Result buffer too small (req: %d, was: %ld)\n", sizeof(THREADENTRY32), lpte->dwSize);
+        return FALSE;
+    }
+    req->handle = handle;
+    req->reset = first;
+    if (server_call( REQ_NEXT_THREAD )) return FALSE;
+    lpte->cntUsage           = req->count;
+    lpte->th32ThreadID       = (DWORD)req->tid;
+    lpte->th32OwnerProcessID = (DWORD)req->pid;
+    lpte->tbBasePri          = req->base_pri; 
+    lpte->tbDeltaPri         = req->delta_pri;
+    lpte->dwFlags            = 0;  /* SDK: "reserved; do not use" */
+    return TRUE;
+}
+
+/***********************************************************************
+ *		Thread32First    (KERNEL32.686)
+ *
+ * Return info about the first thread in a toolhelp32 snapshot
+ */
+BOOL WINAPI Thread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte)
+{
+    return TOOLHELP_Thread32Next(hSnapshot, lpte, TRUE);
+}
+
+/***********************************************************************
+ *		Thread32Next   (KERNEL32.687)
+ *
+ * Return info about the "next" thread in a toolhelp32 snapshot
+ */
+BOOL WINAPI Thread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte)
+{
+    return TOOLHELP_Thread32Next(hSnapshot, lpte, FALSE);
+}
+
+/***********************************************************************
+ *		TOOLHELP_Process32Next
+ *
+ * Implementation of Process32First/Next
+ */
+static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY32 lppe, BOOL first )
+{
+    struct next_process_request *req = get_req_buffer();
+
+    if (lppe->dwSize < sizeof(PROCESSENTRY32))
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        ERR("Result buffer too small (req: %d, was: %ld)\n", sizeof(PROCESSENTRY32), lppe->dwSize);
+        return FALSE;
+    }
+    req->handle = handle;
+    req->reset = first;
+    if (server_call( REQ_NEXT_PROCESS )) return FALSE;
+    lppe->cntUsage            = req->count;
+    lppe->th32ProcessID       = (DWORD)req->pid;
+    lppe->th32DefaultHeapID   = 0;  /* FIXME */ 
+    lppe->th32ModuleID        = 0;  /* FIXME */
+    lppe->cntThreads          = req->threads;
+    lppe->th32ParentProcessID = 0;  /* FIXME */
+    lppe->pcPriClassBase      = req->priority;
+    lppe->dwFlags             = -1; /* FIXME */
+    lppe->szExeFile[0]        = 0;  /* FIXME */
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *		Process32First    (KERNEL32.555)
+ *
+ * Return info about the first process in a toolhelp32 snapshot
+ */
+BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
+{
+    return TOOLHELP_Process32Next( hSnapshot, lppe, TRUE );
+}
+
+/***********************************************************************
+ *		Process32Next   (KERNEL32.556)
+ *
+ * Return info about the "next" process in a toolhelp32 snapshot
+ */
+BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
+{
+    return TOOLHELP_Process32Next( hSnapshot, lppe, FALSE );
+}
+
+
+/***********************************************************************
+ *		TOOLHELP_Module32Next
+ *
+ * Implementation of Module32First/Next
+ */
+static BOOL TOOLHELP_Module32Next( HANDLE handle, LPMODULEENTRY32 lpme, BOOL first )
+{
+    struct next_module_request *req = get_req_buffer();
+    
+    if (lpme->dwSize < sizeof (MODULEENTRY32))
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        ERR("Result buffer too small (req: %d, was: %ld)\n", sizeof(MODULEENTRY32), lpme->dwSize);
+        return FALSE;
+    }
+    req->handle = handle;
+    req->reset = first;
+    if (server_call( REQ_NEXT_MODULE )) return FALSE;
+    lpme->th32ModuleID   = 0;  /* toolhelp internal id, never used */
+    lpme->th32ProcessID  = (DWORD)req->pid;
+    lpme->GlblcntUsage   = 0; /* FIXME */
+    lpme->ProccntUsage   = 0; /* FIXME */ 
+    lpme->modBaseAddr    = req->base;
+    lpme->modBaseSize    = 0; /* FIXME */
+    lpme->hModule        = (DWORD)req->base;
+    lpme->szModule[0]    = 0;  /* FIXME */
+    lpme->szExePath[0]   = 0;  /* FIXME */
+    return TRUE;
+}
+
+/***********************************************************************
+ *		Module32First   (KERNEL32.527)
+ *
+ * Return info about the "first" module in a toolhelp32 snapshot
+ */
+BOOL WINAPI Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
+{
+    return TOOLHELP_Module32Next( hSnapshot, lpme, TRUE );
+}
+
+/***********************************************************************
+ *		Module32Next   (KERNEL32.528)
+ *
+ * Return info about the "next" module in a toolhelp32 snapshot
+ */
+BOOL WINAPI Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
+{
+    return TOOLHELP_Module32Next( hSnapshot, lpme, FALSE );
+}
+
+/************************************************************************
+ *              GlobalMasterHandle16 (KERNEL.28)
+ *
+ *
+ * Should return selector and handle of the information structure for 
+ * the global heap. selector and handle are stored in the THHOOK as
+ * pGlobalHeap and hGlobalHeap.
+ * As Wine doesn't have this structure, we return both values as zero
+ * Applications should interpret this as "No Global Heap"
+ */
+DWORD WINAPI GlobalMasterHandle16(void)
+{
+    FIXME(": stub\n");
+    return 0;
+}