ntdll: Add a platform-specific helper for starting a process.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f8e0bd1b0d
commit
afb16abc0f
|
@ -3028,6 +3028,7 @@ NTSTATUS attach_dlls( void *reserved )
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
attach_implicitly_loaded_dlls( reserved );
|
attach_implicitly_loaded_dlls( reserved );
|
||||||
|
virtual_release_address_space();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3094,14 +3095,6 @@ static void load_global_options(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* start_process
|
|
||||||
*/
|
|
||||||
static void start_process( void *arg )
|
|
||||||
{
|
|
||||||
call_thread_entry_point( kernel32_start_process, arg );
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* LdrInitializeThunk (NTDLL.@)
|
* LdrInitializeThunk (NTDLL.@)
|
||||||
*
|
*
|
||||||
|
@ -3113,7 +3106,6 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
PEB *peb = NtCurrentTeb()->Peb;
|
PEB *peb = NtCurrentTeb()->Peb;
|
||||||
CONTEXT context = { 0 };
|
|
||||||
|
|
||||||
kernel32_start_process = kernel_start;
|
kernel32_start_process = kernel_start;
|
||||||
if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */
|
if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */
|
||||||
|
@ -3145,15 +3137,7 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
|
||||||
InsertHeadList( &peb->LdrData->InMemoryOrderModuleList, &wm->ldr.InMemoryOrderModuleList );
|
InsertHeadList( &peb->LdrData->InMemoryOrderModuleList, &wm->ldr.InMemoryOrderModuleList );
|
||||||
|
|
||||||
if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0, 0 )) != STATUS_SUCCESS) goto error;
|
if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0, 0 )) != STATUS_SUCCESS) goto error;
|
||||||
if ((status = server_init_process_done( &context )) != STATUS_SUCCESS) goto error;
|
status = server_init_process_done();
|
||||||
|
|
||||||
status = wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase - page_size );
|
|
||||||
if (status != STATUS_SUCCESS) goto error;
|
|
||||||
|
|
||||||
virtual_release_address_space();
|
|
||||||
virtual_clear_thread_stack();
|
|
||||||
if (context.ContextFlags) NtSetContextThread( GetCurrentThread(), &context );
|
|
||||||
wine_switch_to_stack( start_process, wm->ldr.EntryPoint, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
ERR( "Main exe initialization for %s failed, status %x\n",
|
ERR( "Main exe initialization for %s failed, status %x\n",
|
||||||
|
|
|
@ -67,7 +67,8 @@ extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HI
|
||||||
extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
|
extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
|
||||||
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry ) DECLSPEC_HIDDEN;
|
extern void signal_init_process(void) DECLSPEC_HIDDEN;
|
||||||
|
extern NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) DECLSPEC_HIDDEN;
|
||||||
extern void version_init( const WCHAR *appname ) DECLSPEC_HIDDEN;
|
extern void version_init( const WCHAR *appname ) DECLSPEC_HIDDEN;
|
||||||
extern void debug_init(void) DECLSPEC_HIDDEN;
|
extern void debug_init(void) DECLSPEC_HIDDEN;
|
||||||
extern HANDLE thread_init(void) DECLSPEC_HIDDEN;
|
extern HANDLE thread_init(void) DECLSPEC_HIDDEN;
|
||||||
|
@ -82,7 +83,7 @@ extern timeout_t server_start_time DECLSPEC_HIDDEN;
|
||||||
extern unsigned int server_cpus DECLSPEC_HIDDEN;
|
extern unsigned int server_cpus DECLSPEC_HIDDEN;
|
||||||
extern BOOL is_wow64 DECLSPEC_HIDDEN;
|
extern BOOL is_wow64 DECLSPEC_HIDDEN;
|
||||||
extern void server_init_process(void) DECLSPEC_HIDDEN;
|
extern void server_init_process(void) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS server_init_process_done( CONTEXT *context ) DECLSPEC_HIDDEN;
|
extern NTSTATUS server_init_process_done(void) DECLSPEC_HIDDEN;
|
||||||
extern size_t server_init_thread( void *entry_point ) DECLSPEC_HIDDEN;
|
extern size_t server_init_thread( void *entry_point ) DECLSPEC_HIDDEN;
|
||||||
extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
|
extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
|
||||||
extern void DECLSPEC_NORETURN terminate_thread( int status ) DECLSPEC_HIDDEN;
|
extern void DECLSPEC_NORETURN terminate_thread( int status ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -1430,7 +1430,7 @@ void server_init_process(void)
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* server_init_process_done
|
* server_init_process_done
|
||||||
*/
|
*/
|
||||||
NTSTATUS server_init_process_done( CONTEXT *context )
|
NTSTATUS server_init_process_done(void)
|
||||||
{
|
{
|
||||||
PEB *peb = NtCurrentTeb()->Peb;
|
PEB *peb = NtCurrentTeb()->Peb;
|
||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
||||||
|
@ -1444,7 +1444,7 @@ NTSTATUS server_init_process_done( CONTEXT *context )
|
||||||
* We do need the handlers in place by the time the request is over, so
|
* We do need the handlers in place by the time the request is over, so
|
||||||
* we set them up here. If we segfault between here and the server call
|
* we set them up here. If we segfault between here and the server call
|
||||||
* something is very wrong... */
|
* something is very wrong... */
|
||||||
signal_init_process( context, entry );
|
signal_init_process();
|
||||||
|
|
||||||
/* Signal the parent process to continue */
|
/* Signal the parent process to continue */
|
||||||
SERVER_START_REQ( init_process_done )
|
SERVER_START_REQ( init_process_done )
|
||||||
|
@ -1460,7 +1460,7 @@ NTSTATUS server_init_process_done( CONTEXT *context )
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (suspend) wait_suspend( context );
|
if (!status) status = signal_start_process( entry, suspend );
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -975,7 +975,7 @@ void signal_init_thread( TEB *teb )
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_process
|
* signal_init_process
|
||||||
*/
|
*/
|
||||||
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
void signal_init_process(void)
|
||||||
{
|
{
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
|
@ -1004,13 +1004,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
sig_act.sa_sigaction = trap_handler;
|
sig_act.sa_sigaction = trap_handler;
|
||||||
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set the initial context */
|
|
||||||
context->ContextFlags = CONTEXT_FULL;
|
|
||||||
context->R0 = (DWORD)kernel32_start_process;
|
|
||||||
context->R1 = (DWORD)entry;
|
|
||||||
context->Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context->Pc = (DWORD)call_thread_entry_point;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1019,6 +1012,29 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.R0 = (DWORD)kernel32_start_process;
|
||||||
|
context.R1 = (DWORD)entry;
|
||||||
|
context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
||||||
|
context.Pc = (DWORD)call_thread_entry_point;
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
|
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase )))
|
||||||
|
set_cpu_context( &context );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -846,7 +846,7 @@ void signal_init_thread( TEB *teb )
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_process
|
* signal_init_process
|
||||||
*/
|
*/
|
||||||
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
void signal_init_process(void)
|
||||||
{
|
{
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
|
@ -875,8 +875,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
sig_act.sa_sigaction = trap_handler;
|
sig_act.sa_sigaction = trap_handler;
|
||||||
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME: set the initial context */
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -885,6 +883,38 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* start_process
|
||||||
|
*/
|
||||||
|
static void start_process( void *arg )
|
||||||
|
{
|
||||||
|
CONTEXT *context = arg;
|
||||||
|
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context->X0, (void *)context->X1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.X0 = (DWORD_PTR)kernel32_start_process;
|
||||||
|
context.X1 = (DWORD_PTR)entry;
|
||||||
|
context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase;
|
||||||
|
context.Pc = (DWORD_PTR)call_thread_entry_point;
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
|
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Sp )))
|
||||||
|
wine_switch_to_stack( start_process, &context, (void *)context.Sp );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2551,7 +2551,7 @@ void signal_init_thread( TEB *teb )
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_process
|
* signal_init_process
|
||||||
*/
|
*/
|
||||||
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
void signal_init_process(void)
|
||||||
{
|
{
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
|
@ -2593,21 +2593,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wine_ldt_init_locking( ldt_lock, ldt_unlock );
|
wine_ldt_init_locking( ldt_lock, ldt_unlock );
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context->ContextFlags = CONTEXT_FULL;
|
|
||||||
context->SegCs = wine_get_cs();
|
|
||||||
context->SegDs = wine_get_ds();
|
|
||||||
context->SegEs = wine_get_es();
|
|
||||||
context->SegFs = wine_get_fs();
|
|
||||||
context->SegGs = wine_get_gs();
|
|
||||||
context->SegSs = wine_get_ss();
|
|
||||||
context->Eax = (DWORD)entry;
|
|
||||||
context->Ebx = (DWORD)NtCurrentTeb()->Peb;
|
|
||||||
context->Esp = (DWORD)NtCurrentTeb()->Tib.StackBase - 16;
|
|
||||||
context->Eip = (DWORD)call_thread_entry_point;
|
|
||||||
((void **)context->Esp)[1] = kernel32_start_process;
|
|
||||||
((void **)context->Esp)[2] = entry;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -2616,6 +2601,41 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.SegCs = wine_get_cs();
|
||||||
|
context.SegDs = wine_get_ds();
|
||||||
|
context.SegEs = wine_get_es();
|
||||||
|
context.SegFs = wine_get_fs();
|
||||||
|
context.SegGs = wine_get_gs();
|
||||||
|
context.SegSs = wine_get_ss();
|
||||||
|
context.Eax = (DWORD)entry;
|
||||||
|
context.Ebx = (DWORD)NtCurrentTeb()->Peb;
|
||||||
|
context.Esp = (DWORD)NtCurrentTeb()->Tib.StackBase - 16;
|
||||||
|
context.Eip = (DWORD)call_thread_entry_point;
|
||||||
|
((void **)context.Esp)[1] = kernel32_start_process;
|
||||||
|
((void **)context.Esp)[2] = entry;
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
|
if (!(status = wine_call_on_stack( attach_dlls, (void *)1,
|
||||||
|
(char *)NtCurrentTeb()->Tib.StackBase - page_size )))
|
||||||
|
{
|
||||||
|
virtual_clear_thread_stack();
|
||||||
|
set_cpu_context( &context );
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __HAVE_VM86
|
#ifdef __HAVE_VM86
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
|
|
|
@ -1048,7 +1048,7 @@ void signal_init_thread( TEB *teb )
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_process
|
* signal_init_process
|
||||||
*/
|
*/
|
||||||
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
void signal_init_process(void)
|
||||||
{
|
{
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
|
@ -1077,8 +1077,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
sig_act.sa_sigaction = trap_handler;
|
sig_act.sa_sigaction = trap_handler;
|
||||||
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME: set the initial context */
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1087,6 +1085,38 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* start_process
|
||||||
|
*/
|
||||||
|
static void start_process( void *arg )
|
||||||
|
{
|
||||||
|
CONTEXT *context = arg;
|
||||||
|
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context->Gpr3, (void *)context->Gpr4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
||||||
|
context.Gpr3 = (DWORD)kernel32_start_process;
|
||||||
|
context.Gpr4 = (DWORD)entry;
|
||||||
|
context.Iar = (DWORD)call_thread_entry_point;
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
|
if (!(wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Gpr1 )))
|
||||||
|
wine_switch_to_stack( start_process, &context, (void *)context.Gpr1 );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3106,7 +3106,7 @@ void signal_init_thread( TEB *teb )
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_process
|
* signal_init_process
|
||||||
*/
|
*/
|
||||||
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
void signal_init_process(void)
|
||||||
{
|
{
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
|
@ -3135,16 +3135,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
sig_act.sa_sigaction = trap_handler;
|
sig_act.sa_sigaction = trap_handler;
|
||||||
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context->ContextFlags = CONTEXT_FULL;
|
|
||||||
__asm__( "movw %%cs,%0" : "=m" (context->SegCs) );
|
|
||||||
__asm__( "movw %%ss,%0" : "=m" (context->SegSs) );
|
|
||||||
__asm__( "fxsave %0" : "=m" (context->u.FltSave) );
|
|
||||||
context->Rcx = (ULONG_PTR)entry;
|
|
||||||
context->Rdx = (ULONG_PTR)NtCurrentTeb()->Peb;
|
|
||||||
context->Rsp = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase - 0x28;
|
|
||||||
context->Rip = (ULONG_PTR)start_process;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -3153,6 +3143,36 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
__asm__( "movw %%cs,%0" : "=m" (context.SegCs) );
|
||||||
|
__asm__( "movw %%ss,%0" : "=m" (context.SegSs) );
|
||||||
|
__asm__( "fxsave %0" : "=m" (context.u.FltSave) );
|
||||||
|
context.Rcx = (ULONG_PTR)entry;
|
||||||
|
context.Rdx = (ULONG_PTR)NtCurrentTeb()->Peb;
|
||||||
|
context.Rsp = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase - 0x28;
|
||||||
|
context.Rip = (ULONG_PTR)start_process;
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
|
if (!(status = wine_call_on_stack( attach_dlls, (void *)1,
|
||||||
|
(char *)NtCurrentTeb()->Tib.StackBase - page_size )))
|
||||||
|
{
|
||||||
|
virtual_clear_thread_stack();
|
||||||
|
set_cpu_context( &context );
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* RtlAddFunctionTable (NTDLL.@)
|
* RtlAddFunctionTable (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue