Some fixes to Wine startup/termination sequence with native USER.
Do not call built-in USER signal handler when using native USER.

diff --git a/if1632/thunk.c b/if1632/thunk.c
index c72a1af..77e866a 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -48,6 +48,7 @@
 extern WORD CALLBACK CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_lwww (FARPROC16,LONG,WORD,WORD,WORD);
 extern WORD CALLBACK CallTo16_word_wwll (FARPROC16,WORD,WORD,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_wwwl (FARPROC16,WORD,WORD,WORD,LONG);
 extern WORD CALLBACK CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
 extern LONG CALLBACK CallTo16_long_llll (FARPROC16,LONG,LONG,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wllwl(FARPROC16,WORD,LONG,LONG,WORD,LONG);
@@ -157,6 +158,7 @@
     (void *)CallTo16_word_www,             /* CallLoadAppSegProc */
     (void *)CallTo16_word_,                /* CallSystemTimerProc */
     (void *)CallTo16_word_www,             /* CallResourceHandlerProc */
+    (void *)CallTo16_word_wwwl,            /* CallPostAppMessageProc */
     (void *)CallTo16_long_l,               /* CallWOWCallbackProc */
     THUNK_WOWCallback16Ex,                 /* CallWOWCallback16Ex */
     (void *)CallTo16_long_l,               /* CallASPIPostProc */
diff --git a/include/callback.h b/include/callback.h
index 25388f9..14f42a9 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -38,6 +38,7 @@
     WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
     VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
     HGLOBAL16 (CALLBACK *CallResourceHandlerProc)( FARPROC16, HGLOBAL16, HMODULE16, HRSRC16 );
+    BOOL16 (CALLBACK *CallPostAppMessageProc)( FARPROC16, HTASK16, UINT16, WPARAM16, LPARAM );
     DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD );
     BOOL32 (CALLBACK *CallWOWCallback16Ex)( FARPROC16, DWORD, DWORD, LPVOID, 
                                             LPDWORD );
diff --git a/loader/main.c b/loader/main.c
index 1c76b07..68c0a78 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -233,11 +233,11 @@
     SetDoubleClickTime32( GetProfileInt32A("windows","DoubleClickSpeed",452) );
 
     /* Create task message queue for the initial task */
-    if ( GetCurrentTask() )
-    {
-        queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
-        if (!SetMessageQueue32( queueSize )) return FALSE;
-    }
+    queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
+    if (!SetMessageQueue32( queueSize )) return FALSE;
+
+    /* Install default USER Signal Handler */
+    SetTaskSignalProc( 0, (FARPROC16)USER_SignalProc );
 
     /* Initialize keyboard driver */
     KEYBOARD_Enable( keybd_event, InputKeyStateTable );
@@ -272,12 +272,6 @@
     /* Initialize KERNEL */
     if (!MAIN_KernelInit(0, 0, NULL)) return 0;
 
-    /* Initialize GDI */
-    if (!MAIN_GdiInit(0, 0, NULL)) return 0;
-
-    /* Initialize USER */
-    if (!MAIN_UserInit(0, 0, NULL)) return 0;
-
     /* Create and switch to initial task */
     if (!(wm = ELF_CreateDummyModule( argv[0], argv[0], PROCESS_Current() )))
         return 0;
@@ -294,7 +288,9 @@
 
     TASK_StartTask( PROCESS_Current()->task );
 
-    InitApp( hInstance );
+    /* Initialize GDI and USER */
+    if (!MAIN_GdiInit(0, 0, NULL)) return 0;
+    if (!MAIN_UserInit(0, 0, NULL)) return 0;
 
     return wm->module;
 }
diff --git a/loader/task.c b/loader/task.c
index 20b430e..4ad4309 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <unistd.h>
 
 #include "windows.h"
 #include "user.h"
@@ -43,6 +44,8 @@
   /* Pointer to function to switch to a larger stack */
 int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
 
+  /* Pointer to debugger callback routine */
+void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask ) = NULL;
 
 static THHOOK DefaultThhook = { 0 };
 THHOOK *pThhook = &DefaultThhook;
@@ -241,11 +244,7 @@
 
         LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE)
                 RVA_PTR(pModule->module32, OptionalHeader.AddressOfEntryPoint);
-        DWORD size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
-        DWORD id;
-        THDB *thdb;
 
-        pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
         if (pModule->heap_size)
             LocalInit( pTask->hInstance, 0, pModule->heap_size );
 
@@ -256,6 +255,11 @@
 #if 1
         ExitProcess( entry(NULL) );
 #else
+{
+        DWORD size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
+        DWORD id;
+        THDB *thdb;
+
         CreateThread( NULL, size, entry, NULL, 0, &id );
         thdb = THREAD_ID_TO_THDB( id );
 
@@ -266,6 +270,7 @@
         }
 
         ExitProcess( thdb->exit_code );
+}
 #endif
     }
     else if (pModule->dos_image)
@@ -322,7 +327,7 @@
                      HINSTANCE16 hPrevInstance, UINT16 cmdShow)
 {
     HTASK16 hTask;
-    TDB *pTask;
+    TDB *pTask, *pInitialTask;
     LPSTR cmd_line;
     WORD sp;
     char *stack32Top;
@@ -421,6 +426,12 @@
     pTask->dta = PTR_SEG_OFF_TO_SEGPTR( pTask->hPDB, 
                                 (int)&pTask->pdb.cmdLine - (int)&pTask->pdb );
 
+    /* Inherit default UserSignalHandler from initial process */
+
+    pInitialTask = (TDB *)GlobalLock16( PROCESS_Initial()->task );
+    if ( pInitialTask )
+        pTask->userhandler = pInitialTask->userhandler;
+
     /* Create the 16-bit stack frame */
 
     if (!(sp = pModule->sp))
@@ -475,6 +486,11 @@
 
     TRACE(task, "linked task %04x\n", hTask );
 
+    /* If requested, add entry point breakpoint */
+
+    if ( TASK_AddTaskEntryBreakpoint )
+        TASK_AddTaskEntryBreakpoint( hTask );
+
     /* Get the task up and running. If we ourselves are a 16-bit task,
        we simply Yield(). If we are 32-bit however, we need to signal
        the main process somehow (NOT YET IMPLEMENTED!) */
@@ -504,15 +520,15 @@
     K32OBJ_DecCount( &pTask->thdb->process->header );
     K32OBJ_DecCount( &pTask->thdb->header );
 
-    /* Free the task module */
-
-    FreeModule16( pTask->hModule );
-
     /* Free the selector aliases */
 
     GLOBAL_FreeBlock( pTask->hCSAlias );
     GLOBAL_FreeBlock( pTask->hPDB );
 
+    /* Free the task module */
+
+    FreeModule16( pTask->hModule );
+
     /* Free the task structure itself */
 
     GlobalFree16( hTask );
@@ -579,12 +595,27 @@
         TASK_DeleteTask( hTaskToKill );
     }
 
-    if (nTaskCount <= 2)    /* FIXME */
+    if (nTaskCount <= 1)
     {
         TRACE(task, "this is the last task, exiting\n" );
         USER_ExitWindows();
     }
 
+    if (!__winelib)
+    {
+    /* FIXME: Hack! Send a message to the initial task so that
+     * the GetMessage wakes up and the initial task can check whether
+     * it is the only remaining one and terminate itself ...
+     * The initial task should probably install hooks or something
+     * to get informed about task termination :-/
+     */
+        HTASK16 hTask = PROCESS_Initial()->task;
+        HMODULE16 hModule = GetModuleHandle16( "USER" );
+        FARPROC16 postFunc = WIN32_GetProcAddress16( hModule, "PostAppMessage" );
+        if (postFunc) 
+            Callbacks->CallPostAppMessageProc( postFunc, hTask, WM_NULL, 0, 0 );
+    }
+
     /* Remove the task from the list to be sure we never switch back to it */
     TASK_UnlinkTask( hCurrentTask );
     if( nTaskCount )
@@ -814,11 +845,6 @@
     if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
     if (!(pModule = NE_GetPtr( pTask->hModule ))) return;
 
-    /* This is a hack to install task USER signal handler before 
-     * implicitly loaded DLLs are initialized (see windows/user.c) */
-
-    pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
-
     /* Initialize implicitly loaded DLLs */
     NE_InitializeDLLs( pTask->hModule );
 
diff --git a/misc/callback.c b/misc/callback.c
index be65ec6..c27eeb3 100644
--- a/misc/callback.c
+++ b/misc/callback.c
@@ -264,6 +264,7 @@
     CALLBACK_CallLoadAppSegProc,      /* CallLoadAppSegProc */
     CALLBACK_CallSystemTimerProc,     /* CallSystemTimerProc */
     CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */
+    NULL,                             /* CallPostAppMessageProc */
     CALLBACK_CallWOWCallbackProc,     /* CallWOWCallbackProc */
     CALLBACK_CallWOWCallback16Ex,     /* CallWOWCallback16Ex */
     CALLBACK_CallASPIPostProc,        /* CallASPIPostProc */
diff --git a/miscemu/main.c b/miscemu/main.c
index 750c1cc..e737976 100644
--- a/miscemu/main.c
+++ b/miscemu/main.c
@@ -51,8 +51,8 @@
 void MAIN_EmulatorRun( void )
 {
     char startProg[256], defProg[256];
-    int i,loaded;
     HINSTANCE32 handle;
+    int i;
 
     BOOL32 (*WINAPI pGetMessage)(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max);
     BOOL32 (*WINAPI pTranslateMessage)( const MSG32* msg );
@@ -78,9 +78,15 @@
 			       startProg, sizeof(startProg) );
     if (startProg[0]) MAIN_argv[MAIN_argc++] = startProg;
 
-    loaded=0;
-    for (i = 1; i < MAIN_argc; i++)
+    /* Abort if no executable on command line */
+    if (MAIN_argc <= 1) 
     {
+    	MAIN_Usage(MAIN_argv[0]);
+        exit(1);
+    }
+
+    /* Load and run executables given on command line */
+    for (i = 1; i < MAIN_argc; i++)
         if ((handle = WinExec32( MAIN_argv[i], SW_SHOWNORMAL )) < 32)
         {
             MSG("wine: can't exec '%s': ", MAIN_argv[i]);
@@ -88,18 +94,9 @@
             {
             case 2: MSG("file not found\n" ); break;
             case 11: MSG("invalid exe file\n" ); break;
-            case 21: MSG("win32 executable\n" ); break; /* FIXME: Obsolete? */
             default: MSG("error=%d\n", handle ); break;
             }
-            ExitProcess( 1 );
         }
-	loaded++;
-    }
-
-    if (!loaded) { /* nothing loaded */
-    	MAIN_Usage(MAIN_argv[0]);
-        ExitProcess( 1 );
-    }
 
     if (GetNumTasks() <= 1)
     {
@@ -107,8 +104,6 @@
         ExitProcess( 0 );
     }
 
-    if (Options.debug) DEBUG_AddModuleBreakpoints();
-
 
     /* Start message loop for desktop window */
 
@@ -141,7 +136,6 @@
     extern char * DEBUG_argv0;
 
     __winelib = 0;  /* First of all, clear the Winelib flag */
-    ctx_debug_call = ctx_debug;
 
     /*
      * Save this so that the internal debugger can get a hold of it if
@@ -168,6 +162,11 @@
         }
     }
 
+    /* Set up debugger callback routines */
+    ctx_debug_call = ctx_debug;
+    if (Options.debug) 
+        TASK_AddTaskEntryBreakpoint = DEBUG_AddTaskEntryBreakpoint;
+
     /* Initialize everything */
     if (!MAIN_EmulatorInit()) return 1;