Get rid of the 32-bit user signal proc since we always run builtin
USER now.  Moved USER module cleanups to the 16-bit signal proc.

diff --git a/dlls/user/user.exe.spec b/dlls/user/user.exe.spec
index 70072c9..02c28a2 100644
--- a/dlls/user/user.exe.spec
+++ b/dlls/user/user.exe.spec
@@ -307,7 +307,7 @@
 #311 CaretBlinkProc # W1.1
 #312 SendMessage2
 #313 PostMessage2
-314 pascal16 SignalProc(word word word word word) USER_SignalProc
+314 pascal16 SignalProc(word word word word word) SignalProc16
 #315 XCStoDS
 #316 CompUpdateRect
 #317 CompUpdateRgn
diff --git a/dlls/user/user16.c b/dlls/user/user16.c
index 26a22c6..9a84728 100644
--- a/dlls/user/user16.c
+++ b/dlls/user/user16.c
@@ -22,8 +22,11 @@
 #include "wine/winuser16.h"
 #include "winbase.h"
 #include "wownt32.h"
+#include "task.h"
 #include "user.h"
 #include "win.h"
+#include "winproc.h"
+#include "cursoricon.h"
 
 /* handle to handle 16 conversions */
 #define HANDLE_16(h32)		(LOWORD(h32))
@@ -455,6 +458,21 @@
 }
 
 
+/***********************************************************************
+ *		SignalProc (USER.314)
+ */
+void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
+                          UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
+{
+    if (code == USIG16_DLL_UNLOAD)
+    {
+        /* HOOK_FreeModuleHooks( hModule ); */
+        CLASS_FreeModuleClasses( hModule );
+        CURSORICON_FreeModuleIcons( hModule );
+    }
+}
+
+
 /**********************************************************************
  *		IsMenu    (USER.358)
  */
diff --git a/include/module.h b/include/module.h
index 0bea592..6931cd0 100644
--- a/include/module.h
+++ b/include/module.h
@@ -214,6 +214,7 @@
 extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule );
 extern void NE_InitializeDLLs( HMODULE16 hModule );
 extern void NE_DllProcessAttach( HMODULE16 hModule );
+extern void NE_CallUserSignalProc( HMODULE16 hModule, UINT16 code );
 
 /* loader/pe_resource.c */
 extern HRSRC PE_FindResourceW(HMODULE,LPCWSTR,LPCWSTR);
@@ -240,28 +241,4 @@
 extern HMODULE16 BUILTIN_LoadModule( LPCSTR name );
 extern BOOL BUILTIN_IsPresent( LPCSTR name );
 
-/* USER signal proc flags and codes */
-/* See PROCESS_CallUserSignalProc for comments */
-#define USIG_FLAGS_WIN32          0x0001
-#define USIG_FLAGS_GUI            0x0002
-#define USIG_FLAGS_FEEDBACK       0x0004
-#define USIG_FLAGS_FAULT          0x0008
-
-#define USIG_DLL_UNLOAD_WIN16     0x0001
-#define USIG_DLL_UNLOAD_WIN32     0x0002
-#define USIG_FAULT_DIALOG_PUSH    0x0003
-#define USIG_FAULT_DIALOG_POP     0x0004
-#define USIG_DLL_UNLOAD_ORPHANS   0x0005
-#define USIG_THREAD_INIT          0x0010
-#define USIG_THREAD_EXIT          0x0020
-#define USIG_PROCESS_CREATE       0x0100
-#define USIG_PROCESS_INIT         0x0200
-#define USIG_PROCESS_EXIT         0x0300
-#define USIG_PROCESS_DESTROY      0x0400
-#define USIG_PROCESS_RUNNING      0x0500
-#define USIG_PROCESS_LOADED       0x0600
-
-/* scheduler/process.c */
-extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule );
-
 #endif  /* __WINE_MODULE_H */
diff --git a/include/user.h b/include/user.h
index 752ecc1..1108e9a 100644
--- a/include/user.h
+++ b/include/user.h
@@ -116,9 +116,6 @@
 
 extern USER_DRIVER USER_Driver;
 
-WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
-                            DWORD dwFlags, HMODULE16 hModule );
-
 /* user lock */
 extern void USER_Lock(void);
 extern void USER_Unlock(void);
diff --git a/loader/ne/module.c b/loader/ne/module.c
index f6469b2..9daded5 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -293,7 +293,7 @@
     NE_MODULE *pModule;
 
     if (!(pModule = NE_GetPtr( hModule ))) return 0;
-    assert( !(pModule->flags & NE_FFLAGS_WIN32) );
+    if (pModule->flags & NE_FFLAGS_WIN32) return 0;
 
     TRACE("(%04x,'%s')\n", hModule, name );
 
@@ -1287,8 +1287,7 @@
             MODULE_CallWEP( hModule );
 
             /* Free the objects owned by the DLL module */
-            TASK_CallTaskSignalProc( USIG16_DLL_UNLOAD, hModule );
-            PROCESS_CallUserSignalProc( USIG_DLL_UNLOAD_WIN16, hModule );
+            NE_CallUserSignalProc( hModule, USIG16_DLL_UNLOAD );
         }
         else
             call_wep = FALSE;  /* We are freeing a task -> no more WEPs */
diff --git a/loader/ne/segment.c b/loader/ne/segment.c
index 2f4e449..83fce73 100644
--- a/loader/ne/segment.c
+++ b/loader/ne/segment.c
@@ -647,7 +647,7 @@
         (pModule->flags & NE_FFLAGS_WIN32)) return TRUE; /*not a library*/
 
     /* Call USER signal handler for Win3.1 compatibility. */
-    TASK_CallTaskSignalProc( USIG16_DLL_LOAD, pModule->self );
+    NE_CallUserSignalProc( pModule->self, USIG16_DLL_LOAD );
 
     if (!pModule->cs) return TRUE;  /* no initialization code */
 
@@ -709,6 +709,31 @@
 }
 
 
+/**********************************************************************
+ *	    NE_CallUserSignalProc
+ *
+ * According to "Undocumented Windows", the task signal proc is
+ * bypassed for module load/unload notifications, and the USER signal
+ * proc is called directly instead. This is what this function does.
+ */
+typedef DWORD (WINAPI *pSignalProc)( HANDLE16 module, UINT16 code, UINT16 exit,
+                                     HINSTANCE16 inst, HQUEUE16 queue );
+
+void NE_CallUserSignalProc( HMODULE16 hModule, UINT16 code )
+{
+    FARPROC16 proc;
+    HMODULE16 user = GetModuleHandle16("user.exe");
+
+    if (!user) return;
+    if ((proc = GetProcAddress16( user, "SignalProc" )))
+    {
+        /* USER is always a builtin dll */
+        pSignalProc sigproc = (pSignalProc)((ENTRYPOINT16 *)MapSL( (SEGPTR)proc ))->target;
+        sigproc( hModule, code, 0, 0, 0 );
+    }
+}
+
+
 /***********************************************************************
  *           NE_CallDllEntryPoint
  *
diff --git a/loader/task.c b/loader/task.c
index 992b5e1..e52ee0f 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -490,9 +490,6 @@
     /* Perform USER cleanup */
 
     TASK_CallTaskSignalProc( USIG16_TERMINATION, pTask->hSelf );
-    PROCESS_CallUserSignalProc( USIG_PROCESS_EXIT, 0 );
-    PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
-    PROCESS_CallUserSignalProc( USIG_PROCESS_DESTROY, 0 );
 
     /* Remove the task from the list to be sure we never switch back to it */
     TASK_UnlinkTask( pTask->hSelf );
diff --git a/scheduler/process.c b/scheduler/process.c
index ed4828b..204e1a2 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -137,116 +137,6 @@
 extern BOOL MAIN_MainInit(void);
 extern void VERSION_Init( const char *appname );
 
-typedef WORD (WINAPI *pUserSignalProc)( UINT, DWORD, DWORD, HMODULE16 );
-
-/***********************************************************************
- *           PROCESS_CallUserSignalProc
- *
- * FIXME:  Some of the signals aren't sent correctly!
- *
- * The exact meaning of the USER signals is undocumented, but this
- * should cover the basic idea:
- *
- * USIG_DLL_UNLOAD_WIN16
- *     This is sent when a 16-bit module is unloaded.
- *
- * USIG_DLL_UNLOAD_WIN32
- *     This is sent when a 32-bit module is unloaded.
- *
- * USIG_DLL_UNLOAD_ORPHANS
- *     This is sent after the last Win3.1 module is unloaded,
- *     to allow removal of orphaned menus.
- *
- * USIG_FAULT_DIALOG_PUSH
- * USIG_FAULT_DIALOG_POP
- *     These are called to allow USER to prepare for displaying a
- *     fault dialog, even though the fault might have happened while
- *     inside a USER critical section.
- *
- * USIG_THREAD_INIT
- *     This is called from the context of a new thread, as soon as it
- *     has started to run.
- *
- * USIG_THREAD_EXIT
- *     This is called, still in its context, just before a thread is
- *     about to terminate.
- *
- * USIG_PROCESS_CREATE
- *     This is called, in the parent process context, after a new process
- *     has been created.
- *
- * USIG_PROCESS_INIT
- *     This is called in the new process context, just after the main thread
- *     has started execution (after the main thread's USIG_THREAD_INIT has
- *     been sent).
- *
- * USIG_PROCESS_LOADED
- *     This is called after the executable file has been loaded into the
- *     new process context.
- *
- * USIG_PROCESS_RUNNING
- *     This is called immediately before the main entry point is called.
- *
- * USIG_PROCESS_EXIT
- *     This is called in the context of a process that is about to
- *     terminate (but before the last thread's USIG_THREAD_EXIT has
- *     been sent).
- *
- * USIG_PROCESS_DESTROY
- *     This is called after a process has terminated.
- *
- *
- * The meaning of the dwFlags bits is as follows:
- *
- * USIG_FLAGS_WIN32
- *     Current process is 32-bit.
- *
- * USIG_FLAGS_GUI
- *     Current process is a (Win32) GUI process.
- *
- * USIG_FLAGS_FEEDBACK
- *     Current process needs 'feedback' (determined from the STARTUPINFO
- *     flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
- *
- * USIG_FLAGS_FAULT
- *     The signal is being sent due to a fault.
- */
-void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule )
-{
-    DWORD dwFlags = 0;
-    HMODULE user;
-    pUserSignalProc proc;
-
-    if (!(user = GetModuleHandleA( "user32.dll" ))) return;
-    if (!(proc = (pUserSignalProc)GetProcAddress( user, "UserSignalProc" ))) return;
-
-    /* Determine dwFlags */
-
-    if ( !(current_process.flags & PDB32_WIN16_PROC) ) dwFlags |= USIG_FLAGS_WIN32;
-    if ( !(current_process.flags & PDB32_CONSOLE_PROC) ) dwFlags |= USIG_FLAGS_GUI;
-
-    if ( dwFlags & USIG_FLAGS_GUI )
-    {
-        /* Feedback defaults to ON */
-        if ( !(current_startupinfo.dwFlags & STARTF_FORCEOFFFEEDBACK) )
-            dwFlags |= USIG_FLAGS_FEEDBACK;
-    }
-    else
-    {
-        /* Feedback defaults to OFF */
-        if (current_startupinfo.dwFlags & STARTF_FORCEONFEEDBACK)
-            dwFlags |= USIG_FLAGS_FEEDBACK;
-    }
-
-    /* Call USER signal proc */
-
-    if ( uCode == USIG_THREAD_INIT || uCode == USIG_THREAD_EXIT )
-        proc( uCode, GetCurrentThreadId(), dwFlags, hModule );
-    else
-        proc( uCode, GetCurrentProcessId(), dwFlags, hModule );
-}
-
-
 /***********************************************************************
  *           get_basename
  */
@@ -555,21 +445,6 @@
 
     MODULE_DllProcessAttach( NULL, (LPVOID)1 );
 
-    /* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
-     *       context of the parent process.  Actually, the USER signal proc
-     *       doesn't really care about that, but it *does* require that the
-     *       startup parameters are correctly set up, so that GetProcessDword
-     *       works.  Furthermore, before calling the USER signal proc the
-     *       16-bit stack must be set up, which it is only after TASK_Create
-     *       in the case of a 16-bit process. Thus, we send the signal here.
-     */
-    PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
-    PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
-    PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
-    PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );
-    /* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
-    if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
-
     if (TRACE_ON(relay))
         DPRINTF( "%04lx:Starting process %s (entryproc=%p)\n",
                  GetCurrentThreadId(), main_exe_name, entry );
diff --git a/scheduler/thread.c b/scheduler/thread.c
index a485ce6..f738300 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -232,7 +232,6 @@
     if (TRACE_ON(relay))
         DPRINTF("%04lx:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
 
-    PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
     MODULE_DllThreadAttach( NULL );
     ExitThread( func( NtCurrentTeb()->entry_arg ) );
 }
diff --git a/windows/user.c b/windows/user.c
index e8c60ef..194233e 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -45,6 +45,28 @@
 SYSLEVEL USER_SysLevel = { CRITICAL_SECTION_INIT("USER_SysLevel"), 2 };
 
 
+/* USER signal proc flags and codes */
+/* See UserSignalProc for comments */
+#define USIG_FLAGS_WIN32          0x0001
+#define USIG_FLAGS_GUI            0x0002
+#define USIG_FLAGS_FEEDBACK       0x0004
+#define USIG_FLAGS_FAULT          0x0008
+
+#define USIG_DLL_UNLOAD_WIN16     0x0001
+#define USIG_DLL_UNLOAD_WIN32     0x0002
+#define USIG_FAULT_DIALOG_PUSH    0x0003
+#define USIG_FAULT_DIALOG_POP     0x0004
+#define USIG_DLL_UNLOAD_ORPHANS   0x0005
+#define USIG_THREAD_INIT          0x0010
+#define USIG_THREAD_EXIT          0x0020
+#define USIG_PROCESS_CREATE       0x0100
+#define USIG_PROCESS_INIT         0x0200
+#define USIG_PROCESS_EXIT         0x0300
+#define USIG_PROCESS_DESTROY      0x0400
+#define USIG_PROCESS_RUNNING      0x0500
+#define USIG_PROCESS_LOADED       0x0600
+
+
 /***********************************************************************
  *		GetFreeSystemResources (USER.284)
  */
@@ -129,26 +151,6 @@
 }
 
 
-/**********************************************************************
- *           USER_ModuleUnload
- */
-static void USER_ModuleUnload( HMODULE16 hModule )
-{
-    /* HOOK_FreeModuleHooks( hModule ); */
-    CLASS_FreeModuleClasses( hModule );
-    CURSORICON_FreeModuleIcons( hModule );
-}
-
-/***********************************************************************
- *		SignalProc (USER.314)
- */
-void WINAPI USER_SignalProc( HANDLE16 hTaskOrModule, UINT16 uCode,
-                             UINT16 uExitFn, HINSTANCE16 hInstance,
-                             HQUEUE16 hQueue )
-{
-    FIXME_(win)("Win 3.1 USER signal %04x\n", uCode );
-}
-
 /***********************************************************************
  *		FinalUserInit (USER.400)
  */
@@ -161,43 +163,79 @@
  *		SignalProc32 (USER.391)
  *		UserSignalProc (USER32.@)
  *
- * For comments about the meaning of uCode and dwFlags
- * see PROCESS_CallUserSignalProc.
+ * The exact meaning of the USER signals is undocumented, but this
+ * should cover the basic idea:
  *
+ * USIG_DLL_UNLOAD_WIN16
+ *     This is sent when a 16-bit module is unloaded.
+ *
+ * USIG_DLL_UNLOAD_WIN32
+ *     This is sent when a 32-bit module is unloaded.
+ *
+ * USIG_DLL_UNLOAD_ORPHANS
+ *     This is sent after the last Win3.1 module is unloaded,
+ *     to allow removal of orphaned menus.
+ *
+ * USIG_FAULT_DIALOG_PUSH
+ * USIG_FAULT_DIALOG_POP
+ *     These are called to allow USER to prepare for displaying a
+ *     fault dialog, even though the fault might have happened while
+ *     inside a USER critical section.
+ *
+ * USIG_THREAD_INIT
+ *     This is called from the context of a new thread, as soon as it
+ *     has started to run.
+ *
+ * USIG_THREAD_EXIT
+ *     This is called, still in its context, just before a thread is
+ *     about to terminate.
+ *
+ * USIG_PROCESS_CREATE
+ *     This is called, in the parent process context, after a new process
+ *     has been created.
+ *
+ * USIG_PROCESS_INIT
+ *     This is called in the new process context, just after the main thread
+ *     has started execution (after the main thread's USIG_THREAD_INIT has
+ *     been sent).
+ *
+ * USIG_PROCESS_LOADED
+ *     This is called after the executable file has been loaded into the
+ *     new process context.
+ *
+ * USIG_PROCESS_RUNNING
+ *     This is called immediately before the main entry point is called.
+ *
+ * USIG_PROCESS_EXIT
+ *     This is called in the context of a process that is about to
+ *     terminate (but before the last thread's USIG_THREAD_EXIT has
+ *     been sent).
+ *
+ * USIG_PROCESS_DESTROY
+ *     This is called after a process has terminated.
+ *
+ *
+ * The meaning of the dwFlags bits is as follows:
+ *
+ * USIG_FLAGS_WIN32
+ *     Current process is 32-bit.
+ *
+ * USIG_FLAGS_GUI
+ *     Current process is a (Win32) GUI process.
+ *
+ * USIG_FLAGS_FEEDBACK
+ *     Current process needs 'feedback' (determined from the STARTUPINFO
+ *     flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
+ *
+ * USIG_FLAGS_FAULT
+ *     The signal is being sent due to a fault.
  */
 WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
                             DWORD dwFlags, HMODULE16 hModule )
 {
-    /* FIXME: Proper reaction to most signals still missing. */
-
-    switch ( uCode )
-    {
-    case USIG_DLL_UNLOAD_WIN16:
-    case USIG_DLL_UNLOAD_WIN32:
-        USER_ModuleUnload( hModule );
-        break;
-
-    case USIG_DLL_UNLOAD_ORPHANS:
-    case USIG_FAULT_DIALOG_PUSH:
-    case USIG_FAULT_DIALOG_POP:
-    case USIG_THREAD_INIT:
-    case USIG_THREAD_EXIT:
-    case USIG_PROCESS_CREATE:
-    case USIG_PROCESS_INIT:
-    case USIG_PROCESS_LOADED:
-    case USIG_PROCESS_RUNNING:
-    case USIG_PROCESS_EXIT:
-    case USIG_PROCESS_DESTROY:
-      break;
-
-    default:
-        FIXME_(win)("(%04x, %08lx, %04lx, %04x)\n",
-                    uCode, dwThreadOrProcessID, dwFlags, hModule );
-        break;
-    }
-
+    FIXME_(win)("(%04x, %08lx, %04lx, %04x)\n",
+                uCode, dwThreadOrProcessID, dwFlags, hModule );
     /* FIXME: Should chain to GdiSignalProc now. */
-
     return 0;
 }