Some fixes to Wine startup/termination sequence with native USER.

Do not call built-in USER signal handler when using native USER.
This commit is contained in:
Ulrich Weigand 1998-11-14 18:45:25 +00:00 committed by Alexandre Julliard
parent b9aa7c9aba
commit afac2e476c
6 changed files with 67 additions and 42 deletions

View File

@ -48,6 +48,7 @@ extern WORD CALLBACK CallTo16_word_llwl (FARPROC16,LONG,LONG,WORD,LONG);
extern WORD CALLBACK CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG); 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_lwww (FARPROC16,LONG,WORD,WORD,WORD);
extern WORD CALLBACK CallTo16_word_wwll (FARPROC16,WORD,WORD,LONG,LONG); 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 WORD CALLBACK CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
extern LONG CALLBACK CallTo16_long_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); extern WORD CALLBACK CallTo16_word_wllwl(FARPROC16,WORD,LONG,LONG,WORD,LONG);
@ -157,6 +158,7 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable =
(void *)CallTo16_word_www, /* CallLoadAppSegProc */ (void *)CallTo16_word_www, /* CallLoadAppSegProc */
(void *)CallTo16_word_, /* CallSystemTimerProc */ (void *)CallTo16_word_, /* CallSystemTimerProc */
(void *)CallTo16_word_www, /* CallResourceHandlerProc */ (void *)CallTo16_word_www, /* CallResourceHandlerProc */
(void *)CallTo16_word_wwwl, /* CallPostAppMessageProc */
(void *)CallTo16_long_l, /* CallWOWCallbackProc */ (void *)CallTo16_long_l, /* CallWOWCallbackProc */
THUNK_WOWCallback16Ex, /* CallWOWCallback16Ex */ THUNK_WOWCallback16Ex, /* CallWOWCallback16Ex */
(void *)CallTo16_long_l, /* CallASPIPostProc */ (void *)CallTo16_long_l, /* CallASPIPostProc */

View File

@ -38,6 +38,7 @@ typedef struct
WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD ); WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 ); VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
HGLOBAL16 (CALLBACK *CallResourceHandlerProc)( FARPROC16, HGLOBAL16, HMODULE16, HRSRC16 ); HGLOBAL16 (CALLBACK *CallResourceHandlerProc)( FARPROC16, HGLOBAL16, HMODULE16, HRSRC16 );
BOOL16 (CALLBACK *CallPostAppMessageProc)( FARPROC16, HTASK16, UINT16, WPARAM16, LPARAM );
DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD ); DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD );
BOOL32 (CALLBACK *CallWOWCallback16Ex)( FARPROC16, DWORD, DWORD, LPVOID, BOOL32 (CALLBACK *CallWOWCallback16Ex)( FARPROC16, DWORD, DWORD, LPVOID,
LPDWORD ); LPDWORD );

View File

@ -233,11 +233,11 @@ BOOL32 WINAPI MAIN_UserInit(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvRes
SetDoubleClickTime32( GetProfileInt32A("windows","DoubleClickSpeed",452) ); SetDoubleClickTime32( GetProfileInt32A("windows","DoubleClickSpeed",452) );
/* Create task message queue for the initial task */ /* 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 */ /* Initialize keyboard driver */
KEYBOARD_Enable( keybd_event, InputKeyStateTable ); KEYBOARD_Enable( keybd_event, InputKeyStateTable );
@ -272,12 +272,6 @@ HINSTANCE32 MAIN_WinelibInit( int *argc, char *argv[] )
/* Initialize KERNEL */ /* Initialize KERNEL */
if (!MAIN_KernelInit(0, 0, NULL)) return 0; 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 */ /* Create and switch to initial task */
if (!(wm = ELF_CreateDummyModule( argv[0], argv[0], PROCESS_Current() ))) if (!(wm = ELF_CreateDummyModule( argv[0], argv[0], PROCESS_Current() )))
return 0; return 0;
@ -294,7 +288,9 @@ HINSTANCE32 MAIN_WinelibInit( int *argc, char *argv[] )
TASK_StartTask( PROCESS_Current()->task ); 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; return wm->module;
} }

View File

@ -7,6 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <unistd.h>
#include "windows.h" #include "windows.h"
#include "user.h" #include "user.h"
@ -43,6 +44,8 @@
/* Pointer to function to switch to a larger stack */ /* Pointer to function to switch to a larger stack */
int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL; int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
/* Pointer to debugger callback routine */
void (*TASK_AddTaskEntryBreakpoint)( HTASK16 hTask ) = NULL;
static THHOOK DefaultThhook = { 0 }; static THHOOK DefaultThhook = { 0 };
THHOOK *pThhook = &DefaultThhook; THHOOK *pThhook = &DefaultThhook;
@ -241,11 +244,7 @@ static void TASK_CallToStart(void)
LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE) LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE)
RVA_PTR(pModule->module32, OptionalHeader.AddressOfEntryPoint); 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) if (pModule->heap_size)
LocalInit( pTask->hInstance, 0, pModule->heap_size ); LocalInit( pTask->hInstance, 0, pModule->heap_size );
@ -256,6 +255,11 @@ static void TASK_CallToStart(void)
#if 1 #if 1
ExitProcess( entry(NULL) ); ExitProcess( entry(NULL) );
#else #else
{
DWORD size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve;
DWORD id;
THDB *thdb;
CreateThread( NULL, size, entry, NULL, 0, &id ); CreateThread( NULL, size, entry, NULL, 0, &id );
thdb = THREAD_ID_TO_THDB( id ); thdb = THREAD_ID_TO_THDB( id );
@ -266,6 +270,7 @@ static void TASK_CallToStart(void)
} }
ExitProcess( thdb->exit_code ); ExitProcess( thdb->exit_code );
}
#endif #endif
} }
else if (pModule->dos_image) else if (pModule->dos_image)
@ -322,7 +327,7 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
HINSTANCE16 hPrevInstance, UINT16 cmdShow) HINSTANCE16 hPrevInstance, UINT16 cmdShow)
{ {
HTASK16 hTask; HTASK16 hTask;
TDB *pTask; TDB *pTask, *pInitialTask;
LPSTR cmd_line; LPSTR cmd_line;
WORD sp; WORD sp;
char *stack32Top; char *stack32Top;
@ -421,6 +426,12 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
pTask->dta = PTR_SEG_OFF_TO_SEGPTR( pTask->hPDB, pTask->dta = PTR_SEG_OFF_TO_SEGPTR( pTask->hPDB,
(int)&pTask->pdb.cmdLine - (int)&pTask->pdb ); (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 */ /* Create the 16-bit stack frame */
if (!(sp = pModule->sp)) if (!(sp = pModule->sp))
@ -475,6 +486,11 @@ void TASK_StartTask( HTASK16 hTask )
TRACE(task, "linked task %04x\n", hTask ); 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, /* 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 we simply Yield(). If we are 32-bit however, we need to signal
the main process somehow (NOT YET IMPLEMENTED!) */ the main process somehow (NOT YET IMPLEMENTED!) */
@ -504,15 +520,15 @@ static void TASK_DeleteTask( HTASK16 hTask )
K32OBJ_DecCount( &pTask->thdb->process->header ); K32OBJ_DecCount( &pTask->thdb->process->header );
K32OBJ_DecCount( &pTask->thdb->header ); K32OBJ_DecCount( &pTask->thdb->header );
/* Free the task module */
FreeModule16( pTask->hModule );
/* Free the selector aliases */ /* Free the selector aliases */
GLOBAL_FreeBlock( pTask->hCSAlias ); GLOBAL_FreeBlock( pTask->hCSAlias );
GLOBAL_FreeBlock( pTask->hPDB ); GLOBAL_FreeBlock( pTask->hPDB );
/* Free the task module */
FreeModule16( pTask->hModule );
/* Free the task structure itself */ /* Free the task structure itself */
GlobalFree16( hTask ); GlobalFree16( hTask );
@ -579,12 +595,27 @@ void TASK_KillCurrentTask( INT16 exitCode )
TASK_DeleteTask( hTaskToKill ); TASK_DeleteTask( hTaskToKill );
} }
if (nTaskCount <= 2) /* FIXME */ if (nTaskCount <= 1)
{ {
TRACE(task, "this is the last task, exiting\n" ); TRACE(task, "this is the last task, exiting\n" );
USER_ExitWindows(); 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 */ /* Remove the task from the list to be sure we never switch back to it */
TASK_UnlinkTask( hCurrentTask ); TASK_UnlinkTask( hCurrentTask );
if( nTaskCount ) if( nTaskCount )
@ -814,11 +845,6 @@ void WINAPI InitTask( CONTEXT *context )
if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return;
if (!(pModule = NE_GetPtr( pTask->hModule ))) 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 */ /* Initialize implicitly loaded DLLs */
NE_InitializeDLLs( pTask->hModule ); NE_InitializeDLLs( pTask->hModule );

View File

@ -264,6 +264,7 @@ static const CALLBACKS_TABLE CALLBACK_WinelibTable =
CALLBACK_CallLoadAppSegProc, /* CallLoadAppSegProc */ CALLBACK_CallLoadAppSegProc, /* CallLoadAppSegProc */
CALLBACK_CallSystemTimerProc, /* CallSystemTimerProc */ CALLBACK_CallSystemTimerProc, /* CallSystemTimerProc */
CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */ CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */
NULL, /* CallPostAppMessageProc */
CALLBACK_CallWOWCallbackProc, /* CallWOWCallbackProc */ CALLBACK_CallWOWCallbackProc, /* CallWOWCallbackProc */
CALLBACK_CallWOWCallback16Ex, /* CallWOWCallback16Ex */ CALLBACK_CallWOWCallback16Ex, /* CallWOWCallback16Ex */
CALLBACK_CallASPIPostProc, /* CallASPIPostProc */ CALLBACK_CallASPIPostProc, /* CallASPIPostProc */

View File

@ -51,8 +51,8 @@ BOOL32 MAIN_EmulatorInit(void)
void MAIN_EmulatorRun( void ) void MAIN_EmulatorRun( void )
{ {
char startProg[256], defProg[256]; char startProg[256], defProg[256];
int i,loaded;
HINSTANCE32 handle; HINSTANCE32 handle;
int i;
BOOL32 (*WINAPI pGetMessage)(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max); BOOL32 (*WINAPI pGetMessage)(MSG32* lpmsg,HWND32 hwnd,UINT32 min,UINT32 max);
BOOL32 (*WINAPI pTranslateMessage)( const MSG32* msg ); BOOL32 (*WINAPI pTranslateMessage)( const MSG32* msg );
@ -78,9 +78,15 @@ void MAIN_EmulatorRun( void )
startProg, sizeof(startProg) ); startProg, sizeof(startProg) );
if (startProg[0]) MAIN_argv[MAIN_argc++] = startProg; if (startProg[0]) MAIN_argv[MAIN_argc++] = startProg;
loaded=0; /* Abort if no executable on command line */
for (i = 1; i < MAIN_argc; i++) 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) if ((handle = WinExec32( MAIN_argv[i], SW_SHOWNORMAL )) < 32)
{ {
MSG("wine: can't exec '%s': ", MAIN_argv[i]); MSG("wine: can't exec '%s': ", MAIN_argv[i]);
@ -88,18 +94,9 @@ void MAIN_EmulatorRun( void )
{ {
case 2: MSG("file not found\n" ); break; case 2: MSG("file not found\n" ); break;
case 11: MSG("invalid exe file\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; default: MSG("error=%d\n", handle ); break;
} }
ExitProcess( 1 );
} }
loaded++;
}
if (!loaded) { /* nothing loaded */
MAIN_Usage(MAIN_argv[0]);
ExitProcess( 1 );
}
if (GetNumTasks() <= 1) if (GetNumTasks() <= 1)
{ {
@ -107,8 +104,6 @@ void MAIN_EmulatorRun( void )
ExitProcess( 0 ); ExitProcess( 0 );
} }
if (Options.debug) DEBUG_AddModuleBreakpoints();
/* Start message loop for desktop window */ /* Start message loop for desktop window */
@ -141,7 +136,6 @@ int main( int argc, char *argv[] )
extern char * DEBUG_argv0; extern char * DEBUG_argv0;
__winelib = 0; /* First of all, clear the Winelib flag */ __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 * Save this so that the internal debugger can get a hold of it if
@ -168,6 +162,11 @@ int main( int argc, char *argv[] )
} }
} }
/* Set up debugger callback routines */
ctx_debug_call = ctx_debug;
if (Options.debug)
TASK_AddTaskEntryBreakpoint = DEBUG_AddTaskEntryBreakpoint;
/* Initialize everything */ /* Initialize everything */
if (!MAIN_EmulatorInit()) return 1; if (!MAIN_EmulatorInit()) return 1;