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:
parent
b9aa7c9aba
commit
afac2e476c
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue