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;