diff --git a/if1632/thunk.c b/if1632/thunk.c
index 10b6223ead0414285f4c7436017ffb53d291ab3e..a682595de2eec77cd4f017f9b5da569dac81c2fd 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -41,6 +41,7 @@ extern LONG CALLBACK THUNK_CallTo16_long_ll   (FARPROC16,LONG,LONG);
 extern WORD CALLBACK THUNK_CallTo16_word_www  (FARPROC16,WORD,WORD,WORD);
 extern WORD CALLBACK THUNK_CallTo16_word_wwl  (FARPROC16,WORD,WORD,LONG);
 extern WORD CALLBACK THUNK_CallTo16_word_wlw  (FARPROC16,WORD,LONG,WORD);
+extern WORD CALLBACK THUNK_CallTo16_word_lllw (FARPROC16,LONG,LONG,LONG,WORD);
 extern WORD CALLBACK THUNK_CallTo16_word_llwl (FARPROC16,LONG,LONG,WORD,LONG);
 extern WORD CALLBACK THUNK_CallTo16_word_lwww (FARPROC16,LONG,WORD,WORD,WORD);
 extern WORD CALLBACK THUNK_CallTo16_word_wlww (FARPROC16,WORD,LONG,WORD,WORD);
@@ -374,7 +375,6 @@ void THUNK_InitCallout(void)
         GETADDR( DispatchMessageW, "DispatchMessageW" );
         GETADDR( DispatchMessageA, "DispatchMessageA" );
         GETADDR( RedrawWindow, "RedrawWindow" );
-        GETADDR( UserSignalProc, "UserSignalProc" );
 
 #undef GETADDR
     }
@@ -399,6 +399,7 @@ void THUNK_InitCallout(void)
         GETADDR( InitThreadInput16, "InitThreadInput", word_ww );
         GETADDR( UserYield16, "UserYield", word_ );
         GETADDR( DestroyIcon32, "DestroyIcon32", word_ww );
+        GETADDR( UserSignalProc, "SignalProc32", word_lllw );
 
 #undef GETADDR
     }
diff --git a/include/process.h b/include/process.h
index 9e370207edb66b942583b0c5126ef80c90983e91..b1d923687bae723c54d6709c5795debf6afdf2d2 100644
--- a/include/process.h
+++ b/include/process.h
@@ -156,7 +156,7 @@ extern BOOL PROCESS_Init( void );
 extern BOOL PROCESS_IsCurrent( HANDLE handle );
 extern PDB *PROCESS_Initial(void);
 extern PDB *PROCESS_IdToPDB( DWORD id );
-extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule );
+extern void PROCESS_CallUserSignalProc( UINT uCode, DWORD dwThreadId, HMODULE hModule );
 extern PDB *PROCESS_Create( struct _NE_MODULE *pModule, 
                             LPCSTR cmd_line, LPCSTR env, 
                             LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
diff --git a/loader/task.c b/loader/task.c
index ca93800ef362bc5fc8f0fa42bea6953e46d165bc..35d8a8e189fd3172b94274ccbdd94edea1a69cf6 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -462,9 +462,9 @@ void TASK_KillTask( HTASK16 hTask )
     /* Perform USER cleanup */
 
     TASK_CallTaskSignalProc( USIG16_TERMINATION, hTask );
-    PROCESS_CallUserSignalProc( USIG_PROCESS_EXIT, 0 );
-    PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );     /* FIXME */
-    PROCESS_CallUserSignalProc( USIG_PROCESS_DESTROY, 0 );
+    PROCESS_CallUserSignalProc( USIG_PROCESS_EXIT, 0, 0 );
+    PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, GetCurrentThreadId(), 0 );
+    PROCESS_CallUserSignalProc( USIG_PROCESS_DESTROY, 0, 0 );
 
     if (nTaskCount <= 1)
     {
@@ -716,6 +716,7 @@ void WINAPI InitTask16( CONTEXT86 *context )
 
     /* Initialize implicitly loaded DLLs */
     NE_InitializeDLLs( pTask->hModule );
+    NE_DllProcessAttach( pTask->hModule );
 
     /* Registers on return are:
      * ax     1 if OK, 0 on error
diff --git a/scheduler/process.c b/scheduler/process.c
index 9aed121fbcc1c96529be0cb1385b7147303ee1b6..a65be8ece2b2c82cb05a434a25274370c65f7375 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -185,9 +185,10 @@ PDB *PROCESS_IdToPDB( DWORD id )
  * USIG_FLAGS_FAULT
  *     The signal is being sent due to a fault.
  */
-static void PROCESS_CallUserSignalProcHelper( UINT uCode, DWORD dwThreadOrProcessId,
-                                              HMODULE hModule, DWORD flags, DWORD startup_flags )
+void PROCESS_CallUserSignalProc( UINT uCode, DWORD dwThreadId, HMODULE hModule )
 {
+    DWORD flags = PROCESS_Current()->flags;
+    DWORD startup_flags = PROCESS_Current()->env_db->startup_info->dwFlags;
     DWORD dwFlags = 0;
 
     /* Determine dwFlags */
@@ -217,26 +218,12 @@ static void PROCESS_CallUserSignalProcHelper( UINT uCode, DWORD dwThreadOrProces
     /* Call USER signal proc */
 
     if ( Callout.UserSignalProc )
-        Callout.UserSignalProc( uCode, dwThreadOrProcessId, dwFlags, hModule );
-}
-
-/* Call USER signal proc for the current thread/process */
-void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule )
-{
-    DWORD dwThreadOrProcessId;
-
-    /* Get thread or process ID */
-    if ( uCode == USIG_THREAD_INIT || uCode == USIG_THREAD_EXIT )
-        dwThreadOrProcessId = GetCurrentThreadId();
-    else
-        dwThreadOrProcessId = GetCurrentProcessId();
-
-    PROCESS_CallUserSignalProcHelper( uCode, dwThreadOrProcessId, hModule,
-                                      PROCESS_Current()->flags,
-                                      PROCESS_Current()->env_db->startup_info->dwFlags );
+        if ( uCode == USIG_THREAD_INIT || uCode == USIG_THREAD_EXIT )
+            Callout.UserSignalProc( uCode, dwThreadId, dwFlags, hModule );
+        else
+            Callout.UserSignalProc( uCode, GetCurrentProcessId(), dwFlags, hModule );
 }
 
-
 /***********************************************************************
  *           PROCESS_CreateEnvDB
  *
@@ -436,14 +423,9 @@ void PROCESS_Start(void)
      *       in the case of a 16-bit process. Thus, we send the signal here.
      */
 
-    /* Load USER32.DLL before calling UserSignalProc (relay debugging!) */
-    LoadLibraryA( "USER32.DLL" );
-
-    PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
-
-    PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );  /* for initial thread */
-
-    PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
+    PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0, 0 );
+    PROCESS_CallUserSignalProc( USIG_THREAD_INIT, GetCurrentThreadId(), 0 );
+    PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0, 0 );
 
     /* Signal the parent process to continue */
     server_call( REQ_INIT_PROCESS_DONE );
@@ -468,7 +450,7 @@ void PROCESS_Start(void)
         PE_InitTls();
     }
 
-    PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );   /* FIXME: correct location? */
+    PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0, 0 );   /* FIXME: correct location? */
 
     if ( (pdb->flags & PDB32_CONSOLE_PROC) || (pdb->flags & PDB32_DOS_PROC) )
         AllocConsole();
@@ -485,7 +467,7 @@ void PROCESS_Start(void)
         TASK_AddTaskEntryBreakpoint( pdb->task );
 
     /* Now call the entry point */
-    PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
+    PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0, 0 );
 
     switch ( type )
     {
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 7ba3a0c528c4bc8aa1c960da3495c8c4b413aa06..e09e634c7a7ef731d4bd95c05fd68b9243addac3 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -150,7 +150,7 @@ void CALLBACK THREAD_FreeTEB( ULONG_PTR arg )
     TRACE("(%p) called\n", teb );
     SERVICE_Delete( teb->cleanup );
 
-    PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
+    PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, (DWORD)teb->tid, 0 );
     
     CloseHandle( teb->event );
     while (*pptr && (*pptr != teb)) pptr = &(*pptr)->next;
@@ -277,7 +277,7 @@ error:
 static void THREAD_Start(void)
 {
     LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)NtCurrentTeb()->entry_point;
-    PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
+    PROCESS_CallUserSignalProc( USIG_THREAD_INIT, (DWORD)NtCurrentTeb()->tid, 0 );
     PE_InitTls();
     MODULE_DllThreadAttach( NULL );